home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / PlainText / TE32K.c < prev    next >
C/C++ Source or Header  |  1994-02-03  |  86KB  |  3,383 lines

  1. #include <CType.h>
  2. #include <ToolUtils.h>
  3. #include "TE32K.h"
  4.  
  5. #define    EXTRALINESTARTS        32
  6. #define    EXTRATEXTBUFF        256
  7.  
  8. #define    LEFTARROW            28
  9. #define    RIGHTARROW            29
  10. #define UPARROW                30
  11. #define DOWNARROW            31
  12. #define    TAB                    '\t'
  13. #define DELETE                0x08
  14. #define    RETURN                0x0D
  15. #define    ENTER                0x03
  16. #define LINEFEED            0x0A
  17. #define BEACHBALL            1
  18.  
  19.  
  20. /*--------------------------- Macros ----------------------------*/
  21.  
  22. #define Clip2Short(n) ((n)<-32768)? -32768:((n)>32767)? 32767:n;
  23. #define mClearCaret(h) if((**h).caretState) xorCaret(h)
  24. /* Carriage return or linefeed */
  25. /* #define isneol(c) (c!='\r'&&c!='\n') */
  26. /* #define iseol(c) (c=='\r'||c=='\n') */
  27.  
  28. /* Carriage return or linefeed but not both (takes pointer ) */
  29.  
  30. /* #define iseol(p) (*p=='\n' || (*p=='\r' && *(p-1)!='\n')) */
  31. /* #define isneol(p) !(iseol(p)) */
  32. /* #define isneol(p) (*p!='\n' && *p!='\r') */
  33.  
  34. #define isneol(c) (c!='\n')
  35. #define iseol(c) (c=='\n')
  36.  
  37. #ifdef MC68000
  38. #pragma segment TE32K
  39. #endif
  40.  
  41. /* Some globals for TE32K */
  42.  
  43. Handle            TE32KScrpHandle = nil;
  44. long            TE32KScrpLength = 0;
  45. long            TE32KAnchor = -1;
  46. long            TE32KHPos = -1;
  47. TE32KHandle        ClickedTE32KH = nil;
  48.  
  49. static long        LineEndIndex(long,TE32KHandle);
  50. static void        CalParagraph(long,TE32KHandle,long *,long *);
  51. static long     paraLines(long,TE32KHandle);
  52. static void     updateLine(long,TE32KHandle,short,LongRect *);
  53. static void     invertSelectRgn(TE32KHandle);
  54. static void     extendHilite(long,long,TE32KHandle);
  55.  
  56. static void     makeSelectRgn(TE32KHandle);
  57.  
  58. void            xorCaret(TE32KHandle);
  59. long            indexToLine(long,TE32KHandle);
  60. long            indexToParagraph(long,TE32KHandle);
  61. /* static short    shiftKeyDown(void); */
  62. /* pascal void     MyClicker(void); */
  63. /* extern pascal void     MyClickLoop(void); */
  64. extern pascal void MyClicker(void);
  65. void positionView(TE32KHandle,long);
  66.  
  67. #ifdef BEACHBALL
  68. #include <Acurs.h>
  69. #endif
  70.  
  71. void TE32KSetFontStuff(short txFont,short txFace,short txMode,short txSize,TE32KHandle tH)
  72. {
  73.     register short        i;
  74.     short                    oldFont,oldFace,oldSize,oldMode;
  75.     GrafPtr                oldPort;
  76.     FontInfo            theFontInfo;
  77.  
  78.  
  79.     (**tH).txFont = txFont;
  80.     (**tH).txFace = txFace;
  81.     (**tH).txMode = txMode;
  82.     (**tH).txSize = txSize;
  83.     
  84.     GetPort(&oldPort);
  85.     SetPort((**tH).inPort);
  86.     oldFont = ((**tH).inPort)->txFont;
  87.     oldFace = ((**tH).inPort)->txFace;
  88.     oldSize = ((**tH).inPort)->txSize;
  89.     oldMode = ((**tH).inPort)->txMode;
  90.     
  91.     TextFont((**tH).txFont);
  92.     TextFace((**tH).txFace);
  93.     TextSize((**tH).txSize);
  94.     TextMode((**tH).txMode);
  95.     
  96.     
  97.     for(i=0;i<256;i++)
  98.         (**tH).theCharWidths[i] = CharWidth((unsigned char) i);
  99.     if((**tH).tabChars)
  100.         (**tH).tabWidth = (**tH).tabChars * (**tH).theCharWidths[' '];
  101.     if((**tH).showInvisibles) {
  102.         for(i=0;i<0x20;i++)
  103.             (**tH).theCharWidths[i] = CharWidth((unsigned char) '¿');
  104.         (**tH).theCharWidths[' '] = CharWidth((unsigned char) '◊');
  105.     }
  106.     GetFontInfo(&theFontInfo);
  107.     
  108.     (**tH).lineHeight = theFontInfo.ascent + theFontInfo.descent + theFontInfo.leading;
  109.     (**tH).fontAscent = theFontInfo.ascent;
  110.     
  111.     TextFont(oldFont);
  112.     TextFace(oldFace);
  113.     TextSize(oldSize);
  114.     TextMode(oldMode);
  115.     
  116.     SetPort(oldPort);
  117. }
  118.  
  119. void SetLongRect(LongRect *theLongRect,long left,long top,long right,long bottom)
  120. {
  121.     theLongRect->left = left;
  122.     theLongRect->top = top;
  123.     theLongRect->right = right;
  124.     theLongRect->bottom = bottom;
  125. }
  126.  
  127. void RectToLongRect(Rect *theRect,LongRect *theLongRect)
  128. {
  129.     theLongRect->left = (long) theRect->left;
  130.     theLongRect->top = (long) theRect->top;
  131.     theLongRect->right = (long) theRect->right;
  132.     theLongRect->bottom = (long) theRect->bottom;
  133. }
  134.  
  135. void LongRectToRect(LongRect *theLongRect,Rect *theRect)
  136. {
  137.     theRect->left=Clip2Short(theLongRect->left);
  138.     theRect->top=Clip2Short(theLongRect->top);
  139.     theRect->right=Clip2Short(theLongRect->right);
  140.     theRect->bottom=Clip2Short(theLongRect->bottom);
  141. }
  142.  
  143. void    OffsetLongRect(LongRect *theLongRect, long x, long y)
  144. {
  145.         theLongRect->left += x;
  146.         theLongRect->top += y;
  147.         theLongRect->right += x;
  148.         theLongRect->bottom += y;
  149. }
  150.  
  151. long indexToParagraph(long selIndex,TE32KHandle tH)
  152. {
  153.     long i;
  154.     char *p;
  155.     
  156.     if(tH) {
  157.         i = indexToLine(selIndex,tH);
  158.         if(!(**tH).crOnly) {
  159.             p = (*(**tH).hText)+(**tH).lineStarts[i]-1;
  160.             while(i>0 && *p != RETURN && *p != LINEFEED) {
  161.                 i--;
  162.                 p =(*(**tH).hText)+(**tH).lineStarts[i]-1;
  163.             }
  164.         }
  165.         return i;
  166.     }
  167.     return 0;
  168. }
  169.  
  170. long indexToLine(long selIndex,TE32KHandle tH)
  171. {
  172.  
  173.     /* This is a binary search into the LineStarts Array. */
  174.     
  175.     register long    i,delta;
  176.  
  177.     if (tH) {
  178.         if (selIndex<=0 || (**tH).nLines<=1 || (**tH).teLength<1)
  179.             return 0;
  180.         
  181.         else if (selIndex >= (**tH).teLength)
  182.             return (**tH).nLines - 1 ;
  183.         
  184.         else {
  185.             i = delta = ((**tH).nLines) >> 1;
  186.             
  187.             delta = ((**tH).nLines) >> 1;
  188.             if (delta < 1)
  189.                 delta = 1;
  190.             
  191.             while (delta > 0) {
  192.                 if (selIndex == (**tH).lineStarts[i])
  193.                     delta = 0;
  194.                 
  195.                 else if (selIndex > (**tH).lineStarts[i]) {
  196.                     if (selIndex < (**tH).lineStarts[i+1])
  197.                         delta = 0;
  198.                     
  199.                     else
  200.                         i += delta;
  201.                 } else
  202.                     i -= delta;
  203.                 
  204.                 if (delta) {
  205.                     delta >>= 1;
  206.                     
  207.                     if (delta < 1)
  208.                         delta = 1;
  209.                 }
  210.             }
  211.         }
  212.         
  213.         if (i < 0)
  214.             i = 0;
  215.         else if (i >= (**tH).nLines)
  216.             i = (**tH).nLines - 1;
  217.         
  218.         return i;
  219.     } else
  220.         return 0;
  221. }
  222.  
  223. void xorCaret(TE32KHandle tH)
  224. {
  225.     GrafPtr            oldPort;
  226.     PenState        oldPenState;
  227.     Point            selPt;
  228.     RgnHandle        oldClipRgn;
  229.     Rect            theClipRect;
  230.  
  231.     if (tH && (**tH).active && (**tH).selStart==(**tH).selEnd) {
  232.         if (!(**tH).caretState && ((**tH).selStart < 0 || (**tH).selEnd > (**tH).teLength))
  233.             return;
  234.             
  235.         if(((**tH).selPoint.v - (**tH).fontAscent) < -32768)
  236.             return;
  237.             
  238.         GetPort(&oldPort);
  239.         SetPort((**tH).inPort);
  240.         
  241.         GetPenState(&oldPenState);
  242.         oldClipRgn = NewRgn();
  243.         GetClip(oldClipRgn);
  244.         
  245.         theClipRect.left = (short) ((**tH).viewRect.left);
  246.         theClipRect.top = (short) ((**tH).viewRect.top);
  247.         theClipRect.right = (short) ((**tH).viewRect.right);
  248.         theClipRect.bottom = (short) ((**tH).viewRect.bottom);
  249.         
  250.         ClipRect(&theClipRect);
  251.         
  252.         PenNormal();
  253.         
  254.         PenMode(patXor);
  255.         selPt.h = Clip2Short((**tH).selPoint.h);
  256.         selPt.v = Clip2Short((**tH).selPoint.v);
  257.                 
  258.         MoveTo(selPt.h - 1,selPt.v);
  259.         Line(0,-(**tH).fontAscent);
  260.         
  261.         (**tH).caretTime = TickCount() + GetCaretTime();
  262.         (**tH).caretState = !(**tH).caretState;
  263.         
  264.         SetClip(oldClipRgn);
  265.         DisposeRgn(oldClipRgn);
  266.         
  267.         SetPenState(&oldPenState);
  268.         SetPort(oldPort);
  269.     }
  270. }
  271.  
  272. void TE32KInit()
  273. {
  274.     TE32KScrpHandle = NewHandle(0);
  275.     TE32KScrpLength = 0;
  276.     TE32KHPos = TE32KAnchor = -1;
  277. }
  278.  
  279. TE32KHandle TE32KNew(LongRect *destRect,LongRect *viewRect)
  280. {
  281.     TE32KHandle        newTE32KHandle;
  282.     Handle            hText;
  283.     GrafPtr            activePort;
  284.     FontInfo        theFontInfo;
  285.     LongPoint        selPt;
  286.  
  287.     newTE32KHandle = (TE32KHandle) NewHandle((long) sizeof(TE32KRec) + (long) sizeof(long)*EXTRALINESTARTS);
  288.     if (MemError() || StripAddress(newTE32KHandle)==nil) {
  289.         doMessage(1);
  290.         return((TE32KHandle) nil);
  291.     }
  292.     
  293.     hText = NewHandle(EXTRATEXTBUFF);
  294.     if (MemError() || StripAddress(hText)==nil) {
  295.         DisposHandle((Handle) newTE32KHandle);
  296.         doMessage(1);
  297.         return((TE32KHandle) nil);
  298.     }
  299.     
  300.     (**newTE32KHandle).destRect = *destRect;
  301.     (**newTE32KHandle).viewRect = *viewRect;
  302.     
  303.     GetPort(&activePort);
  304.     GetFontInfo(&theFontInfo);
  305.     
  306.     (**newTE32KHandle).lineHeight = theFontInfo.ascent + theFontInfo.descent + theFontInfo.leading;
  307.     (**newTE32KHandle).fontAscent = theFontInfo.ascent;
  308.     
  309.     (**newTE32KHandle).selStart = 0;
  310.     (**newTE32KHandle).selEnd = 0;
  311.     
  312.     (**newTE32KHandle).teLength = 0;
  313.     (**newTE32KHandle).hText = hText;
  314.     
  315.     (**newTE32KHandle).txFont = activePort->txFont;
  316.     (**newTE32KHandle).txFace = activePort->txFace;
  317.     (**newTE32KHandle).txMode = activePort->txMode;
  318.     (**newTE32KHandle).txSize = activePort->txSize;
  319.     
  320.     (**newTE32KHandle).inPort = activePort;
  321.     
  322.     (**newTE32KHandle).tabWidth = 24;
  323.     (**newTE32KHandle).tabChars = 4;
  324.     
  325. /*    (**newTE32KHandle).maxLineWidth = 32767;    */
  326.  
  327.     (**newTE32KHandle).maxLineWidth = 75;
  328.     
  329.     (**newTE32KHandle).clikStuff = FALSE;
  330.     
  331.     (**newTE32KHandle).crOnly = 0;
  332.     (**newTE32KHandle).wrapToLength = 0;
  333.     (**newTE32KHandle).autoIndent = 0;
  334.     
  335.     (**newTE32KHandle).showInvisibles = 0;
  336.     
  337.     (**newTE32KHandle).nLines = 1;
  338.     (**newTE32KHandle).lineStarts[0] = 0;
  339.     (**newTE32KHandle).lineStarts[1] = 0;
  340.     
  341.     (**newTE32KHandle).active = TRUE;
  342.     (**newTE32KHandle).caretState = FALSE;
  343.     (**newTE32KHandle).caretTime = TickCount();
  344.     
  345.     (**newTE32KHandle).clickTime = TickCount();
  346.     (**newTE32KHandle).clickLoc = -1;
  347.     
  348.     TE32KGetPoint((**newTE32KHandle).selStart,&selPt,newTE32KHandle);
  349.     
  350.     (**newTE32KHandle).selPoint = selPt;
  351.     
  352.     (**newTE32KHandle).clikLoop = nil;
  353.     (**newTE32KHandle).selRgn = nil;
  354.     
  355.     (**newTE32KHandle).undoBuf = nil;
  356.         
  357.     (**newTE32KHandle).undoStart = 0;
  358.     (**newTE32KHandle).undoEnd = 0;
  359.     (**newTE32KHandle).undoDelta = 0;
  360.     
  361.     (**newTE32KHandle).resetUndo = true;
  362.     
  363.     TE32KSetFontStuff((**newTE32KHandle).txFont,(**newTE32KHandle).txFace,(**newTE32KHandle).txMode,(**newTE32KHandle).txSize,newTE32KHandle);
  364.     
  365.     return((TE32KHandle) newTE32KHandle);
  366. }
  367.  
  368. void TE32KDispose(TE32KHandle tH)
  369. {
  370.     if (tH) {
  371.         if ((**tH).hText)
  372.             DisposHandle((**tH).hText);
  373. #ifdef __UNDOACTION__
  374.         if((**tH).undoBuf)
  375.             DisposeHandle((**tH).undoBuf);
  376. #endif        
  377.         DisposHandle((Handle)tH);
  378.     }
  379. }
  380.  
  381. void TE32KCalText(TE32KHandle tH)
  382. {
  383.     register unsigned char    *charPtr;
  384.     register long            charCount;
  385.     register short            *theCharWidths,lineWidth,maxLineWidth;
  386.     register unsigned char    ch;
  387.     Boolean                    atLineEnd,wrapToLength,crOnly,wrap;
  388.     long                    nLines,maxLineStarts,sizeTE32KHandle;
  389.     unsigned char            *charBase;
  390.     Point                    cursorPt;
  391.     short                    rightSide,destLeftSide,maxRewind;
  392.     unsigned char            *oldCharPtr;
  393.     long                    tabWidth,oldCharCount,tempOffset;
  394.  
  395.     if (tH) {
  396.         (**tH).lineStarts[0] = 0;        /* assume the worst can happen and prepare for it */
  397.         (**tH).lineStarts[1] = 0;
  398.         (**tH).nLines = 1;
  399.         
  400. #ifdef BEACHBALL
  401.         ShowACurs();
  402. #endif
  403.         sizeTE32KHandle  = GetHandleSize((Handle) tH);
  404.         maxLineStarts = (sizeTE32KHandle - (long) sizeof(TE32KRec))/(long) sizeof(long) - 2;
  405.         
  406.         wrapToLength = (**tH).wrapToLength;
  407.         crOnly = (**tH).crOnly;
  408.         maxLineWidth = (!(**tH).crOnly && wrapToLength)? (**tH).maxLineWidth : 32767 ;
  409.         wrap = false;
  410.         
  411.         lineWidth = 0;
  412.         nLines = 0;
  413.         
  414.         charBase = (unsigned char *) *((**tH).hText);
  415.         charPtr = charBase;
  416.         charCount = (**tH).teLength;
  417.         
  418.         
  419.         if (charCount > 0) {
  420.             rightSide = (short) ((**tH).destRect.right);
  421.             destLeftSide = (short) ((**tH).destRect.left + 1);
  422.             cursorPt.h = destLeftSide;
  423.             tabWidth = (**tH).tabWidth;
  424.             
  425.             theCharWidths = (**tH).theCharWidths;
  426.             
  427.             while (charCount--) {
  428.                 ch = *charPtr++;
  429.                 lineWidth++;
  430.                 
  431.                 if(crOnly)
  432.                     atLineEnd =iseol(ch);
  433.                 else if(wrapToLength) {
  434.                     wrap = lineWidth > maxLineWidth;
  435.                     atLineEnd = wrap || iseol(ch) ;
  436.                 } else {
  437.                     if (ch == TAB)
  438.                         cursorPt.h = destLeftSide + ((cursorPt.h - destLeftSide + tabWidth)/tabWidth)*tabWidth;
  439.                     else
  440.                         cursorPt.h += theCharWidths[ch];
  441.                     
  442.                     wrap = (ch != ' ' && cursorPt.h >= rightSide);    
  443.                     atLineEnd = wrap || iseol(ch); 
  444.                 }
  445.                 
  446.                 if (atLineEnd) {
  447. #ifdef BEACHBALL
  448.                     SpinACurs(0);
  449. #endif
  450.                     if (wrap) {
  451.                         /* I should probably add a hook for custom word-breaking */
  452.                         
  453.                         maxRewind = charPtr - charBase - (**tH).lineStarts[nLines];
  454.                         oldCharPtr = charPtr;
  455.                         oldCharCount = charCount;
  456.                         
  457.                         charPtr--;
  458.                         charCount++;
  459.                         maxRewind--;
  460.                         
  461.                         while (*charPtr != ' ' && maxRewind > 0) {
  462.                             charPtr--;
  463.                             charCount++;
  464.                             maxRewind--;
  465.                         }
  466.                         
  467.                         if (maxRewind <= 0) {
  468.                             charPtr = oldCharPtr;
  469.                             charCount = oldCharCount;
  470.                         } else {
  471.                             charPtr++;
  472.                             charCount--;
  473.                         }
  474.                     }
  475.                     
  476.                     if (nLines >= maxLineStarts) {
  477.                         tempOffset = charPtr - charBase;
  478.                                                 
  479.                         sizeTE32KHandle = (long) sizeof(TE32KRec) + (long) sizeof(long)*(nLines + EXTRALINESTARTS);
  480.                         maxLineStarts = (sizeTE32KHandle - (long) sizeof(TE32KRec))/(long) sizeof(long) - 2;
  481.                         
  482.                         SetHandleSize((Handle) tH,sizeTE32KHandle);
  483.                         
  484.                         if (MemError()) {
  485. #ifdef BEACHBALL
  486.                             HideACurs();
  487. #endif
  488.                             doMessage(1);
  489.                             return;
  490.                         }
  491.                         
  492.                         charBase = (unsigned char *) *((**tH).hText);
  493.                         charPtr = charBase + tempOffset;
  494.                         theCharWidths = (**tH).theCharWidths;
  495.                     }
  496.                     
  497.                     (**tH).lineStarts[++nLines] = charPtr - charBase;
  498.                     
  499.                     cursorPt.h = destLeftSide;
  500.                     lineWidth = 0;
  501.                 }
  502.             }
  503.             
  504. #ifdef BEACHBALL
  505.             HideACurs();
  506. #endif
  507.             if (nLines >= maxLineStarts) {
  508.                 sizeTE32KHandle = (long) sizeof(TE32KRec) + (long) sizeof(long)*(nLines + EXTRALINESTARTS);
  509.                 
  510.                 SetHandleSize((Handle) tH,sizeTE32KHandle);
  511.                 
  512.                 if (MemError()) {
  513.                     doMessage(1);
  514.                     return;
  515.                 }
  516.             }
  517.             
  518.             (**tH).lineStarts[++nLines] = charPtr - charBase;
  519.             (**tH).nLines = nLines;
  520.         }
  521.     }
  522. }
  523.  
  524. void TE32KUseTextHandle(Handle hText,TE32KHandle tH)
  525. {
  526.     LongPoint    selPt;
  527.     long textLength;
  528.  
  529.     if (tH) {
  530.         textLength = GetHandleSize(hText);
  531.  
  532.         if ((**tH).hText)
  533.             DisposHandle((**tH).hText);
  534.                 
  535.         (**tH).hText = hText;
  536.         (**tH).teLength = textLength;
  537.         
  538.         (**tH).selStart = textLength;
  539.         (**tH).selEnd = textLength;
  540.         
  541.         TE32KGetPoint((**tH).selStart,&selPt,tH);
  542.         (**tH).selPoint = selPt;
  543.         
  544.         TE32KCalText(tH);
  545.     }
  546. }
  547.  
  548. void TE32KSetText(Ptr textPtr,long textLength,TE32KHandle tH)
  549. {
  550.     Handle        hText;
  551.     LongPoint    selPt;
  552.  
  553.     if (tH) {
  554.         hText = NewHandle(textLength + EXTRATEXTBUFF);
  555.         
  556.         if (MemError() || StripAddress(hText)==nil) {
  557.             doMessage(1);
  558.             return;
  559.         }
  560.         
  561.         if ((**tH).hText)
  562.             DisposHandle((**tH).hText);
  563.         
  564.         HLock(hText);
  565.         BlockMove(textPtr,*hText,textLength);
  566.         HUnlock(hText);
  567.         
  568.         (**tH).hText = hText;
  569.         (**tH).teLength = textLength;
  570.         
  571.         (**tH).selStart = textLength;
  572.         (**tH).selEnd = textLength;
  573.         
  574.         TE32KGetPoint((**tH).selStart,&selPt,tH);
  575.         (**tH).selPoint = selPt;
  576.         
  577.         TE32KCalText(tH);
  578.     }
  579. }
  580.  
  581. Handle TE32KGetText(TE32KHandle tH) 
  582. {
  583.     Handle hText;
  584.     
  585.     if (tH) {
  586.         hText = (**tH).hText;
  587.         HandToHand(&hText);
  588.         return hText;
  589.     } else
  590.         return nil;
  591. }
  592.  
  593. void TE32KUpdate(LongRect *updateLongRect,TE32KHandle tH) 
  594. {
  595.     LongRect                    tempLongRect;
  596.     Rect                        theClipRect,viewRect,updateRect;
  597.     GrafPtr                        oldPort,currentPort;
  598.     RgnHandle                    oldClipRgn;
  599.     register unsigned char        *textPtr;
  600.     register long                firstLine,lastLine,i,thisStart,nextStart,tabWidth;
  601.     Point                        cursorPt;
  602.     short                        oldFont,oldFace,oldSize,oldMode;
  603.     short                        rightSide,destLeftSide;
  604.     LongPoint                    selPt;
  605.     unsigned char                oldCaretState;
  606.  
  607.     if (tH && (**tH).inPort) {
  608.         tempLongRect = (**tH).viewRect;
  609.         LongRectToRect(&tempLongRect,&viewRect);
  610.         
  611.         tempLongRect = *updateLongRect;
  612.         tempLongRect.top = (**tH).destRect.top + ((updateLongRect->top - (**tH).destRect.top)/(**tH).lineHeight)*(**tH).lineHeight;
  613.         tempLongRect.bottom = (**tH).destRect.top + ((updateLongRect->bottom - (**tH).destRect.top + (**tH).lineHeight - 1)/(**tH).lineHeight)*(**tH).lineHeight;
  614.         
  615.         LongRectToRect(&tempLongRect,&updateRect);
  616.         
  617.         if (SectRect(&viewRect,&updateRect,&theClipRect)) {
  618.             GetPort(&oldPort);
  619.             currentPort = (**tH).inPort;
  620.             SetPort(currentPort);
  621.             
  622.             oldClipRgn = NewRgn();
  623.             GetClip(oldClipRgn);
  624.             ClipRect(&theClipRect);
  625.             
  626.             oldCaretState = (**tH).caretState;
  627.             
  628.             if ((**tH).selStart == (**tH).selEnd && oldCaretState)
  629.                 xorCaret(tH);
  630.             
  631.             firstLine = ((long) theClipRect.top - (**tH).destRect.top)/(long) (**tH).lineHeight;
  632.             lastLine = ((long) theClipRect.bottom - (**tH).destRect.top - 1)/(long) (**tH).lineHeight;
  633.             
  634.             if (firstLine < 0)
  635.                 firstLine = 0;
  636.             
  637.             if (lastLine >= (**tH).nLines)
  638.                 lastLine = (**tH).nLines - 1;
  639.             
  640.             if (firstLine > lastLine)
  641.                 lastLine = firstLine;
  642.             
  643.             EraseRect(&theClipRect);
  644.             
  645.             if (firstLine < (**tH).nLines && (**tH).teLength > 0) {
  646.                 rightSide = theClipRect.right;
  647.                 destLeftSide = (short) (**tH).destRect.left + 1;
  648.                 cursorPt.h = destLeftSide;
  649.                 cursorPt.v = (short) ((**tH).destRect.top + firstLine * (long) (**tH).lineHeight + (long) (**tH).fontAscent);
  650.                 
  651.                 oldFont = ((**tH).inPort)->txFont;
  652.                 oldFace = ((**tH).inPort)->txFace;
  653.                 oldSize = ((**tH).inPort)->txSize;
  654.                 oldMode = ((**tH).inPort)->txMode;
  655.                 
  656.                 TextFont((**tH).txFont);
  657.                 TextFace((**tH).txFace);
  658.                 TextSize((**tH).txSize);
  659.                 TextMode((**tH).txMode);
  660.                 
  661.                 HLock((**tH).hText);
  662.                 
  663.                 textPtr = (unsigned char *) *((**tH).hText);
  664.                 tabWidth = (long) (**tH).tabWidth;
  665.                 
  666.                 while (firstLine <= lastLine) {
  667.                     thisStart = (**tH).lineStarts[firstLine];
  668.                     i = thisStart;
  669.                     
  670.                     nextStart = (**tH).lineStarts[firstLine+1];
  671.                     
  672.                     if (nextStart > thisStart && iseol(textPtr[nextStart-1]))
  673.                         nextStart--;
  674.                     
  675.                     MoveTo(cursorPt.h,cursorPt.v);
  676.                     
  677.                     if((**tH).showInvisibles) {
  678.                         while (thisStart < nextStart) {
  679.                             while (i<nextStart && textPtr[i]>=0x20 && !isspace(textPtr[i]))
  680.                                 i++;
  681.  
  682.                             if (i > thisStart)
  683.                                 DrawText(&(textPtr[thisStart]),0,(short) (i - thisStart));
  684.                             
  685.                             if(i<nextStart) {
  686.                                 if (textPtr[i]==TAB) {
  687.                                     DrawChar('Δ');
  688.                                     MoveTo(destLeftSide + ((currentPort->pnLoc.h - destLeftSide + tabWidth)/tabWidth)*tabWidth,currentPort->pnLoc.v);
  689.                                 } else if(textPtr[i]==' ')
  690.                                     DrawChar('◊');
  691.                                 else if(textPtr[i]=='\n')
  692.                                     DrawChar('¬');
  693.                                 else 
  694.                                     DrawChar('¿');
  695.                                 i++;
  696.                             }
  697.                             
  698.                             thisStart = i;
  699.                             
  700.                             if (currentPort->pnLoc.h > theClipRect.right)
  701.                                 thisStart = nextStart;
  702.                         }
  703.                         if(i<(**tH).teLength && textPtr[i]=='\n')
  704.                             DrawChar('¬');
  705.                     } else {
  706.                         while (thisStart < nextStart) {
  707.                             while (i<nextStart && textPtr[i]!=TAB)
  708.                                 i++;
  709.                             
  710.                             if (i > thisStart)
  711.                                 DrawText(&(textPtr[thisStart]),0,(short) (i - thisStart));
  712.                             
  713.                             if (i<nextStart && textPtr[i]==TAB) {
  714.                                 MoveTo(destLeftSide + ((currentPort->pnLoc.h - destLeftSide + tabWidth)/tabWidth)*tabWidth,currentPort->pnLoc.v);
  715.                                 i++;
  716.                             }
  717.                             
  718.                             thisStart = i;
  719.                             
  720.                             if (currentPort->pnLoc.h > theClipRect.right)
  721.                                 thisStart = nextStart;
  722.                         }
  723.                     }
  724.                     firstLine++;
  725.                     cursorPt.v += (**tH).lineHeight;
  726.                 }
  727.                 
  728.                 HUnlock((**tH).hText);
  729.                 
  730.                 TextFont(oldFont);
  731.                 TextFace(oldFace);
  732.                 TextSize(oldSize);
  733.                 TextMode(oldMode);
  734.             }
  735.             
  736.             if ((**tH).selStart < (**tH).selEnd)
  737.                 invertSelectRgn(tH);        /*  show the selection */
  738.             
  739.             else {
  740.                 TE32KGetPoint((**tH).selStart,&selPt,tH);
  741.                 (**tH).selPoint = selPt;
  742.                 
  743.                 if (oldCaretState)
  744.                     xorCaret(tH);
  745.             }
  746.             
  747.             SetClip(oldClipRgn);
  748.             DisposeRgn(oldClipRgn);
  749.             
  750.             SetPort(oldPort);
  751.         }
  752.     }
  753. }
  754.  
  755. void TE32KScroll(long horiz,long vert,TE32KHandle tH)
  756. {
  757.     LongRect    updateLongRect;
  758.     Rect        scrollRect;
  759.     RgnHandle    updateRgn;
  760.     GrafPtr        oldPort;
  761.     LongPoint    selPt;
  762.  
  763.     if (tH && (**tH).inPort && (horiz || vert)) {
  764.         GetPort(&oldPort);
  765.         SetPort((**tH).inPort);
  766.         
  767.         (**tH).destRect.left += horiz;
  768.         (**tH).destRect.right += horiz;
  769.         (**tH).selPoint.h += horiz;
  770.         
  771.         (**tH).destRect.top += vert;
  772.         (**tH).destRect.bottom += vert;
  773.         (**tH).selPoint.v += vert;
  774.         
  775.         selPt = (**tH).selPoint;
  776.         
  777.         scrollRect.left = ((**tH).viewRect.left);
  778.         scrollRect.top = ((**tH).viewRect.top);
  779.         scrollRect.right = ((**tH).viewRect.right);
  780.         scrollRect.bottom = ((**tH).viewRect.bottom);
  781.         
  782.         if (horiz < ((**tH).viewRect.right-(**tH).viewRect.left) ||
  783.                 vert < ((**tH).viewRect.bottom-(**tH).viewRect.top)) {
  784.             updateRgn = NewRgn();
  785.             
  786.             ScrollRect(&scrollRect,(short) horiz,(short) vert,updateRgn);
  787.             
  788.             updateLongRect.left = (**updateRgn).rgnBBox.left;
  789.             updateLongRect.top = (**updateRgn).rgnBBox.top;
  790.             updateLongRect.right = (**updateRgn).rgnBBox.right;
  791.             updateLongRect.bottom = (**updateRgn).rgnBBox.bottom;
  792.             
  793.             DisposeRgn(updateRgn);
  794.             
  795.             if((**tH).selRgn && (**tH).selStart!=(**tH).selEnd)
  796.                 OffsetRgn((**tH).selRgn,(short) horiz,(short) vert);
  797.                 
  798.             TE32KUpdate(&updateLongRect,tH);
  799.             
  800.             mClearCaret(tH);
  801.             
  802.             (**tH).selPoint = selPt;
  803.             
  804.             xorCaret(tH);
  805.         } else {
  806.             updateLongRect = (**tH).viewRect;
  807.             
  808.             TE32KUpdate(&updateLongRect,tH);
  809.             
  810.             mClearCaret(tH);
  811.             
  812.             (**tH).selPoint = selPt;
  813.             
  814.             xorCaret(tH);
  815.         }
  816.         
  817.         SetPort(oldPort);
  818.     }
  819. }
  820.  
  821. void TE32KActivate(TE32KHandle tH)
  822. {
  823.     if (tH && !((**tH).active)) {
  824.         invertSelectRgn(tH);        /*  Remove frame */
  825.         (**tH).active = TRUE;
  826.         (**tH).caretState = FALSE;
  827.         TE32KAnchor = -1;
  828.         invertSelectRgn(tH);        /*  Hilite selection */
  829.     }
  830. }
  831.  
  832. void TE32KIdle(TE32KHandle tH)
  833. {
  834.     if (tH && (**tH).active && TickCount() >= (**tH).caretTime) {
  835.         if ((**tH).selStart == (**tH).selEnd)
  836.             xorCaret(tH);
  837.     }
  838. }
  839.  
  840. void TE32KDeactivate(TE32KHandle tH)
  841. {
  842.     if (tH && (**tH).active) {
  843.         invertSelectRgn(tH);        /*  Remove hilite */
  844.         (**tH).active = FALSE;
  845.         invertSelectRgn(tH);        /*  Add frame */
  846.     }
  847. }
  848.  
  849. void TE32KGetPoint(long selIndex,LongPoint *selPt,TE32KHandle tH)
  850. {
  851.     register unsigned char    *textPtr;
  852.     register short            *theCharWidths;
  853.     register long            i,thisStart,tabWidth;
  854.     long                    x,destLeftSide;
  855.     LongPoint                origPt;
  856.     short                    clikStuff;
  857.  
  858.     if (tH) {
  859.         if (selIndex<=0 || (**tH).teLength<1) {
  860.             selPt->h = (**tH).destRect.left + 1;
  861.             selPt->v = (**tH).destRect.top + (**tH).fontAscent;
  862.             (**tH).clikStuff = FALSE;
  863.             return;
  864.         }
  865.         
  866.         clikStuff = (**tH).clikStuff;
  867.         (**tH).clikStuff = FALSE;
  868.         
  869.         origPt = *selPt;
  870.         
  871.         i = indexToLine(selIndex,tH);
  872.         
  873.         selPt->v = (**tH).destRect.top + ((**tH).lineHeight * i) + (**tH).fontAscent;
  874.         
  875.         if (!(**tH).crOnly && clikStuff && i > 0 && selIndex == (**tH).lineStarts[i]) {
  876.             i--;
  877.             selPt->v -= (**tH).lineHeight;
  878.         } else if (selIndex < (**tH).lineStarts[i] || (selIndex == (**tH).lineStarts[i] && i < 1)) {
  879.             selPt->h = (**tH).destRect.left + 1;
  880.             return;
  881.         }
  882.         
  883.         HLock((**tH).hText);
  884.         
  885.         textPtr = (unsigned char *) *((**tH).hText);
  886.         
  887.         destLeftSide = (**tH).destRect.left + 1;
  888.         x = destLeftSide;
  889.         
  890.         theCharWidths = (**tH).theCharWidths;
  891.         
  892.         if (isneol(textPtr[selIndex-1])) {
  893.             tabWidth = (**tH).tabWidth;
  894.             
  895.             for(thisStart = (**tH).lineStarts[i];thisStart < selIndex;thisStart++) {                
  896.                 if (*(textPtr+thisStart) == TAB)
  897.                     x = destLeftSide + ((x - destLeftSide + tabWidth)/tabWidth)*tabWidth;
  898.                 else
  899.                     x += *(theCharWidths + *(textPtr+thisStart));
  900.             }
  901.         }
  902.         
  903.         HUnlock((**tH).hText);
  904.         
  905.         selPt->h = x;
  906.     }
  907. }
  908.  
  909. long    TE32KGetOffset(LongPoint *selPt,TE32KHandle tH)
  910. {
  911.     register unsigned char    *textPtr;
  912.     register short            *theCharWidths;
  913.     register long            i,delta,firstChar,lastChar,tabWidth;
  914.     unsigned char            done;
  915.     long                    x,y,selIndex,horiz,destLeftSide;
  916.  
  917.     if (tH) {
  918.         if ((**tH).teLength < 1)
  919.             return 0;
  920.         
  921.         horiz = selPt->h;
  922.         
  923.         y = selPt->v - (**tH).destRect.top;
  924.         
  925.         i = y / (long) (**tH).lineHeight;
  926.         
  927.         if (i < 0)
  928.             return 0;
  929.         
  930.         if (i >= (**tH).nLines)
  931.             return((**tH).teLength);
  932.         
  933.         theCharWidths = (**tH).theCharWidths;
  934.         
  935.         HLock((**tH).hText);
  936.         
  937.         textPtr = (unsigned char *) *((**tH).hText);
  938.         
  939.         destLeftSide = (**tH).destRect.left + 1;
  940.         x = destLeftSide;
  941.         delta = 0;
  942.         
  943.         firstChar = (**tH).lineStarts[i];
  944.         lastChar = (**tH).lineStarts[i+1];
  945.         
  946.         tabWidth = (long) (**tH).tabWidth;
  947.         
  948.         if (firstChar<lastChar && x+delta<horiz) {
  949.             done = FALSE;
  950.         
  951.             while (!done) {
  952.                 if (textPtr[firstChar] != TAB)
  953.                     delta = theCharWidths[textPtr[firstChar]];
  954.                 else
  955.                     delta = (destLeftSide + ((x - destLeftSide + tabWidth)/tabWidth)*tabWidth) - x;
  956.                 
  957.                 firstChar++;
  958.                 
  959.                 if (firstChar >= lastChar) {    
  960.                     if (iseol(textPtr[lastChar - 1]))
  961.                         selIndex = lastChar - 1;
  962.                     else
  963.                         selIndex = lastChar;
  964.                     
  965.                     done = TRUE;
  966.                 } else if (x+delta >= horiz) {
  967.                     if (horiz >= x + (delta >> 1))
  968.                         selIndex = firstChar;
  969.                     else
  970.                         selIndex = --firstChar;
  971.                     
  972.                     done = TRUE;
  973.                 } else
  974.                     x += delta;
  975.             }
  976.         } else
  977.             selIndex = firstChar;
  978.  
  979.         HUnlock((**tH).hText);
  980.         
  981.         return selIndex;
  982.     }
  983. }
  984.  
  985. static void invertSelectRgn(TE32KHandle tH)
  986. {
  987.     Rect        viewRect;
  988.     RgnHandle    viewRgn;
  989.     GrafPtr        oldPort;
  990.  
  991.     if(tH) {            
  992.         if((**tH).selStart == (**tH).selEnd) {
  993.             if((**tH).active && (**tH).caretState)
  994.                 xorCaret(tH);        /*===== eventually make this a dashed line ======*/
  995.         } else if( (**tH).selRgn) {
  996.             viewRect.left = (**tH).viewRect.left;
  997.             viewRect.top = (**tH).viewRect.top;
  998.             viewRect.right = (**tH).viewRect.right;
  999.             viewRect.bottom = (**tH).viewRect.bottom;
  1000.         
  1001.             GetPort(&oldPort);
  1002.             SetPort((**tH).inPort);
  1003.             viewRgn=NewRgn();
  1004.             RectRgn(viewRgn,&viewRect);
  1005.             SectRgn(viewRgn,(**tH).selRgn,viewRgn);
  1006.             if (!EmptyRgn(viewRgn)) {
  1007.                 BitClr((void *)HiliteMode,pHiliteBit);
  1008.                 if((**tH).active)
  1009.                     InvertRgn(viewRgn);
  1010.                 else {
  1011.                     PenSize(1,1);
  1012.                     PenMode(patXor);
  1013.                     FrameRgn(viewRgn);
  1014.                 }
  1015.             }
  1016.             SetPort(oldPort);
  1017.             DisposeRgn(viewRgn);
  1018.         }
  1019.     }
  1020. }
  1021.  
  1022. static void extendHilite(long extStart,long extEnd,TE32KHandle tH)
  1023. {
  1024.     long         firstLine,lastLine;
  1025.     Rect        viewRect,tR,theRect;
  1026.     LongPoint    selPt;
  1027.     RgnHandle    extRgn,tempRgn=0;
  1028.     GrafPtr        oldPort;
  1029.     int temp;
  1030.     
  1031.     if(tH && (**tH).active) {
  1032.         if((**tH).caretState)
  1033.             xorCaret(tH);
  1034.             
  1035.         if(extStart==extEnd)
  1036.             return;
  1037.         
  1038.         if(!(extRgn=NewRgn()))
  1039.             return;
  1040.             
  1041.         viewRect.left = (**tH).viewRect.left;
  1042.         viewRect.top = (**tH).viewRect.top;
  1043.         viewRect.right = (**tH).viewRect.right;
  1044.         viewRect.bottom = (**tH).viewRect.bottom;
  1045.         
  1046.         GetPort(&oldPort);
  1047.         SetPort((**tH).inPort);
  1048.  
  1049.         if (extStart > extEnd) {
  1050.             firstLine = extStart;
  1051.             extStart = extEnd;
  1052.             extEnd = firstLine;
  1053.         }
  1054.             
  1055.         firstLine = indexToLine(extStart,tH);
  1056.         lastLine = indexToLine(extEnd,tH);
  1057.         
  1058.         TE32KGetPoint(extStart,&selPt,tH);
  1059.         selPt.v -= (**tH).fontAscent;
  1060.         
  1061.         if(extStart<=(**tH).selStart)
  1062.             selPt.h--;
  1063. /*         else if(*(*(**tH).hText+extStart)==RETURN) */
  1064.         else if((selPt.h-viewRect.left)==1)
  1065.             selPt.h--;
  1066.         tR.left = Clip2Short(selPt.h);
  1067.         tR.top  = Clip2Short(selPt.v);
  1068.         
  1069.         /* frame the first line */
  1070.         if (firstLine != lastLine) {
  1071.             tR.right = 2000;
  1072.             tR.bottom = tR.top + (**tH).lineHeight;
  1073.         } else {
  1074.             TE32KGetPoint(extEnd,&selPt,tH);
  1075.             selPt.v -= (**tH).fontAscent;
  1076.             selPt.v += (**tH).lineHeight;
  1077.             if(extEnd<(**tH).selEnd)
  1078.                 selPt.h--;
  1079.             tR.right = Clip2Short(selPt.h);
  1080.             tR.bottom = Clip2Short(selPt.v);
  1081.         }
  1082.         if (SectRect(&viewRect,&tR,&theRect)) {
  1083.             BitClr((void *)HiliteMode,pHiliteBit);
  1084.             InvertRect(&theRect);
  1085.         }
  1086.         RectRgn(extRgn,&tR);
  1087.         temp = GetHandleSize((Handle)extRgn);
  1088.         
  1089.         /* If there are middle lines, frame them. */
  1090.         
  1091.         if (lastLine > firstLine+1) {
  1092.             TE32KGetPoint(extEnd,&selPt,tH);
  1093.             
  1094.             tR.left = viewRect.left;
  1095.             tR.top = tR.bottom;
  1096.             tR.right = 2000;
  1097.             
  1098.             selPt.v -= (**tH).fontAscent;
  1099.             
  1100.             tR.bottom = Clip2Short(selPt.v);
  1101.             
  1102.             selPt.v += (**tH).fontAscent;
  1103.             
  1104.             if (SectRect(&viewRect,&tR,&theRect)) {
  1105.                 BitClr((void *)HiliteMode,pHiliteBit);
  1106.                 InvertRect(&theRect);
  1107.             }
  1108.             if(tempRgn=NewRgn()) {
  1109.                 RectRgn(tempRgn,&tR);
  1110.                 UnionRgn(extRgn,tempRgn,extRgn);
  1111.             }
  1112.             temp = GetHandleSize((Handle)extRgn);
  1113.         }
  1114.         /* If there is a last line, frame it. */
  1115.         
  1116.         if (lastLine > firstLine && extEnd > (**tH).lineStarts[lastLine]) {
  1117.             if (lastLine == firstLine+1) 
  1118.                 TE32KGetPoint(extEnd,&selPt,tH);
  1119.             
  1120.             selPt.v -= (**tH).fontAscent;
  1121.             tR.top = Clip2Short(selPt.v);
  1122.             selPt.v += (**tH).lineHeight;
  1123.             tR.bottom = Clip2Short(selPt.v);
  1124.             tR.left = viewRect.left;
  1125.             if(extEnd<(**tH).selEnd)
  1126.                 selPt.h--;
  1127.             tR.right = Clip2Short(selPt.h);
  1128.             
  1129.             if (SectRect(&viewRect,&tR,&theRect)) {
  1130.                 BitClr((void *)HiliteMode,pHiliteBit);
  1131.                 InvertRect(&theRect);
  1132.             }
  1133.             if(!tempRgn)
  1134.                 tempRgn=NewRgn();
  1135.             if(tempRgn) {
  1136.                 RectRgn(tempRgn,&tR);
  1137.                 UnionRgn(extRgn,tempRgn,extRgn);
  1138.             }
  1139.             temp = GetHandleSize((Handle)extRgn);
  1140.         }
  1141.         if(tempRgn)
  1142.             DisposeRgn(tempRgn);
  1143.         SetPort(oldPort);
  1144.         tempRgn=(**tH).selRgn;
  1145.         if(extStart<(**tH).selStart || extEnd>(**tH).selEnd) 
  1146.             UnionRgn(tempRgn,extRgn,tempRgn);
  1147.         else
  1148.             DiffRgn(tempRgn,extRgn,tempRgn);
  1149.         DisposeRgn(extRgn);
  1150.     }
  1151. }
  1152.  
  1153. static void makeSelectRgn(TE32KHandle tH)
  1154. {
  1155.     long        firstLine,lastLine;
  1156.     Rect        viewRect,tR;
  1157.     LongPoint    selPt;
  1158.     GrafPtr        oldPort;
  1159.     RgnHandle    selRgn;
  1160.     int temp;
  1161.  
  1162.     if (tH) {
  1163.         if((**tH).selRgn)
  1164.             SetEmptyRgn((**tH).selRgn);
  1165.         else
  1166.             (**tH).selRgn = NewRgn();
  1167.         if ((**tH).selStart == (**tH).selEnd) {
  1168.             TE32KGetPoint((**tH).selStart,&selPt,tH);
  1169.             (**tH).selPoint = selPt;
  1170.             return;
  1171.         }
  1172.         if(selRgn = (**tH).selRgn) {
  1173.             GetPort(&oldPort);
  1174.             SetPort((**tH).inPort);
  1175.             
  1176.             OpenRgn();
  1177.             viewRect.left = (**tH).viewRect.left;
  1178.             viewRect.top = (**tH).viewRect.top;
  1179.             viewRect.right = (**tH).viewRect.right;
  1180.             viewRect.bottom = (**tH).viewRect.bottom;
  1181.             
  1182.             if ((**tH).selStart > (**tH).selEnd) {
  1183.                 firstLine = (**tH).selStart;
  1184.                 (**tH).selStart = (**tH).selEnd;
  1185.                 (**tH).selEnd = firstLine;
  1186.             }
  1187.             
  1188.             firstLine = indexToLine((**tH).selStart,tH);
  1189.             lastLine = indexToLine((**tH).selEnd,tH);
  1190.             TE32KGetPoint((**tH).selStart,&selPt,tH);
  1191.             selPt.v -= (**tH).fontAscent;
  1192. /*             if ((**tH).selStart >= (**tH).lineStarts[firstLine]) */
  1193.                 selPt.h--;
  1194.             tR.left = Clip2Short(selPt.h);
  1195.             tR.top  = Clip2Short(selPt.v); 
  1196.             
  1197.             /* frame the first line */
  1198.             if (firstLine != lastLine) {
  1199. /*                 tR.right = viewRect.right;    */
  1200.                 tR.right = 2000;
  1201.                 tR.bottom = tR.top + (**tH).lineHeight;
  1202.             } else {
  1203.                 TE32KGetPoint((**tH).selEnd,&selPt,tH);
  1204.                 selPt.v -= (**tH).fontAscent;
  1205.                 selPt.v += (**tH).lineHeight;
  1206.                 tR.right = Clip2Short(selPt.h);
  1207.                 tR.bottom = Clip2Short(selPt.v);
  1208.             }
  1209.             FrameRect(&tR);
  1210.             
  1211.             /* If there are middle lines, frame them. */
  1212.             
  1213.             if (lastLine > firstLine+1) {
  1214.                 TE32KGetPoint((**tH).selEnd,&selPt,tH);
  1215.                 tR.left = viewRect.left;
  1216.                 tR.top = tR.bottom;
  1217. /*                 tR.right = viewRect.right;    */
  1218.                 tR.right = 2000;
  1219.                 selPt.v -= (**tH).fontAscent;
  1220.                 tR.bottom = Clip2Short(selPt.v);
  1221.                 selPt.v += (**tH).fontAscent;
  1222.                 FrameRect(&tR);
  1223.             }
  1224.             
  1225.             /* If there is a last line, frame it. */
  1226.             
  1227.             if (lastLine > firstLine && (**tH).selEnd > (**tH).lineStarts[lastLine]) {
  1228.                 if (lastLine == firstLine+1) 
  1229.                     TE32KGetPoint((**tH).selEnd,&selPt,tH);
  1230.                 selPt.v -= (**tH).fontAscent;
  1231.                 tR.top = Clip2Short(selPt.v);
  1232.                 selPt.v += (**tH).lineHeight;
  1233.                 tR.bottom = Clip2Short(selPt.v);
  1234.                 tR.left = viewRect.left;
  1235.                 tR.right = Clip2Short(selPt.h);
  1236.                 FrameRect(&tR);
  1237.             }
  1238.             CloseRgn(selRgn);
  1239.             SetPort(oldPort);
  1240.             temp = GetHandleSize((Handle)selRgn);
  1241.         }
  1242.     }
  1243. }
  1244.  
  1245. #if 0
  1246. char islbracket(char c) 
  1247. {
  1248.     if(c=='(') return ')';
  1249.     if(c=='{') return '}';
  1250.     if(c=='[') return ']';
  1251.     if(c=='/') return '/';
  1252.     return 0;
  1253. }
  1254. #endif
  1255.  
  1256. char islbracket(char c) 
  1257. {
  1258.     return (c=='(')? ')':
  1259.         (c=='{')? '}':
  1260.         (c=='[')? ']':
  1261.         (c=='/')? '/': 0;
  1262. }
  1263.  
  1264. char isrbracket(char c) 
  1265. {
  1266.     if(c==')') return '(';
  1267.     if(c=='}') return '{';
  1268.     if(c==']') return '[';
  1269.     return 0;
  1270. }
  1271.  
  1272. void TE32KClick(Point startPoint,unsigned char extend,TE32KHandle tH)
  1273. {
  1274.     register long                i,selAnchor,selLast,teLength;
  1275.     register unsigned char        *s;
  1276.     unsigned char                lmatch=0,rmatch=0;
  1277.     short                        cnt;
  1278.     LongPoint                    selPt,tempPt;
  1279.     Point                        mousePt;
  1280.     GrafPtr                        oldPort;
  1281.     long                        oldClickLoc,tokenStart,tokenEnd;
  1282.     static short                 ClickLevel=0;
  1283.     Boolean                        matching=false;
  1284.  
  1285.     if (tH && (**tH).active) {
  1286.         (**tH).resetUndo = true;
  1287.         ClickedTE32KH = tH;
  1288.         TE32KHPos = TE32KAnchor = -1;
  1289.         teLength = (**tH).teLength;
  1290.         
  1291.         mClearCaret(tH);
  1292.         
  1293.         selPt.h = (long) startPoint.h;
  1294.         selPt.v = (long) startPoint.v;
  1295.         
  1296.         oldClickLoc = (**tH).clickLoc;
  1297.         
  1298.         i = TE32KGetOffset(&selPt,tH);
  1299.         i = (i < 0)? 0 : (i > teLength)? teLength : i;
  1300.         (**tH).clickLoc = i;
  1301.             
  1302.         ClickLevel = (teLength > 0 && oldClickLoc == i &&
  1303.                         TickCount() < (**tH).clickTime + GetDblTime()) ? 
  1304.                             ClickLevel+1 : 0 ;
  1305.     
  1306.         tokenStart=tokenEnd=i;
  1307.         
  1308.         s=(unsigned char *) *(**tH).hText;
  1309.         
  1310.         if(ClickLevel==1) {                /*  Selection method for double click: */
  1311.             if(isalnum(*(s+tokenStart))) {    /*  Select a word    */
  1312.                 for(;tokenStart>0 && isalnum(*(s+tokenStart-1));tokenStart--);            
  1313.                 for(;tokenEnd<teLength && isalnum(*(s+tokenEnd));tokenEnd++);
  1314.             } else if(rmatch=islbracket(lmatch=*(s+tokenStart))) {
  1315.                 matching=true;
  1316.                 for(tokenStart++,tokenEnd++,cnt=1;cnt;cnt--) {
  1317.                     for(;tokenEnd<teLength && rmatch!=*(s+tokenEnd);tokenEnd++)
  1318.                         if(*(s+tokenEnd)==lmatch) cnt++;
  1319.                     if(cnt>1) tokenEnd++;
  1320.                 }
  1321.             } else if(lmatch=isrbracket(rmatch=*(s+tokenStart))) {
  1322.                 matching=true;
  1323.                 for(cnt=1;cnt;cnt--) {
  1324.                     for(tokenStart--;tokenStart>0 && lmatch!=*(s+tokenStart-1);tokenStart--)
  1325.                         if(*(s+tokenStart-1)==rmatch) cnt++;
  1326.                 }
  1327.             } else
  1328.                 tokenEnd++;
  1329.         } else if(ClickLevel) {            /*  Selection method for triple click: */
  1330.             for(;tokenStart>0 && isneol(*(s+tokenStart-1));tokenStart--) ;
  1331.             for(;tokenEnd<teLength && isneol(*(s+tokenEnd));tokenEnd++) ;
  1332.             tokenEnd++;
  1333.         }
  1334.         tokenStart = (tokenStart<0)? 0 : tokenStart;
  1335.         tokenEnd = (tokenEnd>teLength)? teLength : tokenEnd;
  1336.         
  1337.         if(!ClickLevel) {
  1338.             GetPort(&oldPort);
  1339.             SetPort((**tH).inPort);
  1340.         }
  1341.  
  1342.         if(extend) {
  1343.             if (tokenEnd >= (**tH).selEnd) {
  1344.                 selAnchor = (**tH).selStart;
  1345.                 selLast = (**tH).selEnd;
  1346.             } else {
  1347.                 selAnchor = (**tH).selEnd;
  1348.                 selLast = (**tH).selStart;
  1349.             }
  1350.             goto DOHILITE;
  1351.         } else {
  1352.             if ((**tH).selStart != (**tH).selEnd) {
  1353.                 invertSelectRgn(tH);                                        /*  Deselect */
  1354.                 if((**tH).selRgn)
  1355.                     SetEmptyRgn((**tH).selRgn);
  1356.             }
  1357.             
  1358.             (**tH).selStart = selAnchor = tokenStart;
  1359.             (**tH).selEnd = selLast = tokenEnd;
  1360.             makeSelectRgn(tH);
  1361.             
  1362.             (**tH).clikStuff = FALSE;
  1363.             TE32KGetPoint(i,&selPt,tH);
  1364.             
  1365.             if ((**tH).crOnly)
  1366.                 (**tH).selPoint = selPt;
  1367.             else {
  1368.                 (**tH).clikStuff = TRUE;
  1369.                 TE32KGetPoint(i,&tempPt,tH);
  1370.                 
  1371.                 if ((selPt.h - startPoint.h)*(selPt.h - startPoint.h) + (selPt.v - startPoint.v)*(selPt.v - startPoint.v) <
  1372.                     (tempPt.h - startPoint.h)*(tempPt.h - startPoint.h) + (tempPt.v - startPoint.v)*(tempPt.v - startPoint.v))
  1373.                         (**tH).selPoint = selPt;
  1374.                 else
  1375.                         (**tH).selPoint = tempPt;
  1376.             }
  1377.             invertSelectRgn(tH);                                            /*  Hilite */
  1378.         }
  1379.         
  1380.         while (StillDown()) {
  1381.             
  1382.             if ((**tH).clikLoop)
  1383.                 (*((**tH).clikLoop)) ();
  1384.             
  1385.             GetMouse(&mousePt);
  1386.             selPt.h = (long) mousePt.h;
  1387.             selPt.v = (long) mousePt.v;
  1388.             
  1389.             i = TE32KGetOffset(&selPt,tH);
  1390.             tokenStart=tokenEnd=i;
  1391.             teLength=(**tH).teLength;
  1392.             
  1393.             if(ClickLevel==1) {                /*  Selection method for double click: */
  1394.                 if(matching) {
  1395.                     for(tokenStart++,cnt=1;cnt;cnt--) {
  1396.                         for(;tokenStart>0 && lmatch!=*(s+tokenStart-1);tokenStart--)
  1397.                             if(*(s+tokenStart-1)==rmatch) cnt++;
  1398.                     }
  1399.                     if(tokenStart>tokenEnd) tokenEnd=tokenStart;
  1400.                     for(cnt=1;cnt;cnt--) {
  1401.                         for(;tokenEnd<teLength && rmatch!=*(s+tokenEnd);tokenEnd++)
  1402.                             if(*(s+tokenEnd)==lmatch) cnt++;
  1403.                         if(cnt>1) tokenEnd++;
  1404.                     }
  1405.                 } else {
  1406.                     for(;tokenStart>0 && isalnum(*(s+tokenStart-1)); tokenStart--) ;            
  1407.                     for(;tokenEnd<teLength && isalnum(*(s+tokenEnd));tokenEnd++) ;
  1408.                 }
  1409.             } else if(ClickLevel) {            /*  Selection method for triple click: */
  1410.                 for(;tokenStart>0 && isneol(*(s+tokenStart-1));tokenStart--) ;
  1411.                 for(;tokenEnd<teLength && isneol(*(s+tokenEnd));tokenEnd++) ;
  1412.                 tokenEnd++;
  1413.             }
  1414.             tokenStart = (tokenStart<0)? 0 : tokenStart;
  1415.             tokenEnd = (tokenEnd>teLength)? teLength : tokenEnd;
  1416.         
  1417.  DOHILITE:
  1418.              if(extend) {
  1419.                 if (selLast >= selAnchor) {                            /*  extending down in text */
  1420.                     if (tokenEnd>selLast) {    
  1421.                         extendHilite(selLast,tokenEnd,tH);            /*  extend selection */
  1422.                         (**tH).selEnd = selLast = tokenEnd;
  1423.                     } else if (tokenEnd>=selAnchor && tokenEnd<selLast) {
  1424.                         extendHilite(tokenEnd,selLast,tH);            /*  shorten selection */
  1425.                         (**tH).selEnd = selLast = tokenEnd;
  1426.                     } else if (tokenStart<selAnchor && tokenEnd<selLast) {
  1427.                         extendHilite(selAnchor,selLast,tH);            /*  extend selection in other direction, remove old hiliting */
  1428.                         extendHilite(tokenStart,selAnchor,tH);            /* add new */
  1429.                         (**tH).selStart = selLast = tokenStart;
  1430.                         (**tH).selEnd = selAnchor;
  1431.                     }
  1432.                 } else {                                                /* extending up in text */
  1433.                     if (tokenStart<selLast) {
  1434.                         extendHilite(tokenStart,selLast,tH);            /* extend selection */
  1435.                         (**tH).selStart = selLast = tokenStart;
  1436.                     } else if (tokenStart<=selAnchor && tokenStart>selLast) {
  1437.                         extendHilite(selLast,tokenStart,tH);            /* shorten selection 8? */
  1438.                         (**tH).selStart = selLast = tokenStart;
  1439.                     } else if (tokenEnd>selAnchor) {
  1440.                         extendHilite(selLast,selAnchor,tH);        /*  extend selection in other direction, remove old hiliting */
  1441.                         extendHilite(selAnchor,tokenEnd,tH);        /*  add new */
  1442.                         (**tH).selStart = selAnchor;
  1443.                         (**tH).selEnd = selLast= tokenEnd;
  1444.                     }
  1445.                 }
  1446.             } else {
  1447.                 if(tokenEnd<=selLast && selLast<(**tH).selEnd) {
  1448.                     extendHilite(selLast,(**tH).selEnd,tH);                /* deselect */
  1449.                     (**tH).selEnd=selLast;
  1450.                 } else if(tokenEnd > (**tH).selEnd ||
  1451.                     (tokenEnd<(**tH).selEnd && tokenEnd>selLast)) {
  1452.                     extendHilite((**tH).selEnd,tokenEnd,tH);            /* deselect */
  1453.                     (**tH).selEnd=tokenEnd;
  1454.                 }
  1455.                 
  1456.                 if(tokenStart>=selAnchor && selAnchor>(**tH).selStart) {
  1457.                     extendHilite((**tH).selStart,selAnchor,tH);            /* Add to selection */
  1458.                     (**tH).selStart=selAnchor;
  1459.                 } else if(tokenStart < (**tH).selStart ||
  1460.                     (tokenStart>(**tH).selStart && tokenStart<selAnchor)) {
  1461.                     extendHilite(tokenStart,(**tH).selStart,tH);        /*  Add to selection */
  1462.                     (**tH).selStart=tokenStart;
  1463.                 }
  1464.             }
  1465.         }    /*  end while */
  1466.         
  1467.         if(!ClickLevel) 
  1468.             SetPort(oldPort);
  1469.         (**tH).clickTime = TickCount();
  1470.         
  1471.         ClickedTE32KH = 0;
  1472.     }
  1473. }
  1474.  
  1475. void TE32KSetSelect(long selStart,long selEnd,TE32KHandle tH)
  1476. {
  1477.     long teLength;
  1478.     
  1479.     if (tH) {
  1480.         if((**tH).selStart < (**tH).selEnd || (**tH).caretState)
  1481.             invertSelectRgn(tH);            /*  Deselect */
  1482.         if((**tH).selRgn)
  1483.             SetEmptyRgn((**tH).selRgn);
  1484.             
  1485.         teLength=(**tH).teLength;
  1486.         
  1487.         if(selStart>teLength) {
  1488.             selStart=teLength;
  1489.             selEnd=teLength;
  1490.         } else {
  1491.             if(selStart<0)
  1492.                 selStart=0;
  1493.             
  1494.             if(selEnd<0)
  1495.                 selEnd=selStart;
  1496.             else if(selEnd>teLength)
  1497.                 selEnd=teLength;
  1498.         }
  1499.             
  1500.         if (selStart <= selEnd) {
  1501.             (**tH).selStart = selStart;
  1502.             (**tH).selEnd = selEnd;
  1503.         } else {
  1504.             (**tH).selStart = selEnd;
  1505.             (**tH).selEnd = selStart;
  1506.         }
  1507.         makeSelectRgn(tH);
  1508.         invertSelectRgn(tH);                /*  Hilite new selection */
  1509.         
  1510.         TE32KHPos = TE32KAnchor = -1;
  1511.     }
  1512. }
  1513.  
  1514. OSErr TE32KToScrap(void)
  1515. {
  1516.     OSErr err;
  1517.  
  1518.     if (TE32KScrpHandle && TE32KScrpLength > 0) {
  1519.         if ((err = ZeroScrap()) != noErr)
  1520.             return(err);
  1521.  
  1522.         HLockHi(TE32KScrpHandle);
  1523.  
  1524.         if ((err = PutScrap(TE32KScrpLength,'TEXT',(Ptr) *TE32KScrpHandle)) != noErr)
  1525.             return(err);
  1526.  
  1527.         HUnlock(TE32KScrpHandle);
  1528.  
  1529.         return(noErr);
  1530.     }
  1531.     
  1532.     return(noScrapErr);
  1533. }
  1534.  
  1535. OSErr TE32KFromScrap(void)
  1536. {
  1537.     long offset;
  1538.     PScrapStuff sInfo;
  1539.     long len;
  1540.  
  1541.     sInfo = InfoScrap();
  1542.     if (TE32KScrpHandle && (len = GetScrap(0,'TEXT',&offset)) > 0) {
  1543.         TE32KScrpLength = GetScrap(TE32KScrpHandle,'TEXT',&offset);
  1544.         
  1545.         if (TE32KScrpLength > 0)
  1546.             return(noErr);
  1547.         
  1548.         else if (TE32KScrpLength == 0)
  1549.             return(noTypeErr);
  1550.         
  1551.         else
  1552.             return(TE32KScrpLength);
  1553.     }
  1554.     
  1555.     if (TE32KScrpHandle == NULL)
  1556.         return(noScrapErr);
  1557.     
  1558.     else
  1559.         return((OSErr)len);
  1560. }
  1561.  
  1562. void TE32KCopy(TE32KHandle tH)
  1563. {
  1564.     if (tH && TE32KScrpHandle && 
  1565.         (**tH).selStart < (**tH).selEnd) {
  1566.         SetHandleSize(TE32KScrpHandle,(**tH).selEnd - (**tH).selStart);
  1567.         
  1568.         if (!MemError() && 
  1569.             GetHandleSize(TE32KScrpHandle) >= ((**tH).selEnd - (**tH).selStart)) {
  1570.             TE32KScrpLength = (**tH).selEnd - (**tH).selStart;
  1571.             
  1572.             HLock(TE32KScrpHandle);
  1573.             HLock((**tH).hText);
  1574.             
  1575.             BlockMove(*((**tH).hText) + (**tH).selStart,
  1576.                 *TE32KScrpHandle,TE32KScrpLength);
  1577.             
  1578.             HUnlock((**tH).hText);
  1579.             HUnlock(TE32KScrpHandle);
  1580.         } else 
  1581.             doMessage(1);
  1582.     }
  1583. }
  1584.  
  1585. void TE32KCut(TE32KHandle tH)
  1586. {
  1587.     if (tH && 
  1588.         TE32KScrpHandle && 
  1589.         (**tH).selStart < (**tH).selEnd) {
  1590.         TE32KCopy(tH);
  1591.         TE32KDelete(tH);
  1592.     }
  1593. }
  1594.  
  1595. #ifdef __UNDOACTION__
  1596.  
  1597. /*-------------------------------------------------------------------
  1598.     Undo works by replacing the selection bounded by undoStart and
  1599.     undoEnd with the contents of the undo buffer. A key point is 
  1600.     that since (**tH).undoBuf is nulled before TE32KDelete is called,
  1601.     the deleted selection is saved in a new undo buffer. The new
  1602.     selection is the length of the undo buffer.
  1603.     
  1604.     Operations that are to be undone need to keep the undoBuf
  1605.     properly filled, and undoStart and undoEnd correct. 
  1606. --------------------------------------------------------------------*/
  1607.  
  1608. void TE32KUndo(TE32KHandle tH)
  1609. {
  1610.     Handle undoH;
  1611.     long len;
  1612.     
  1613.     if(tH) {
  1614.         undoH = (**tH).undoBuf;
  1615.         (**tH).undoBuf=0;
  1616.         if((**tH).undoStart<(**tH).undoEnd) {
  1617.             TE32KSetSelect((**tH).undoStart,(**tH).undoEnd,tH);
  1618.             TE32KDelete(tH);
  1619.         } else {
  1620. /*             (**tH).undoStart=(**tH).undoEnd;    */
  1621.             TE32KSetSelect((**tH).undoEnd,(**tH).undoEnd,tH);
  1622.         }
  1623.         if(undoH) {
  1624.             HLock(undoH);
  1625.             TE32KInsert(*undoH,len=GetHandleSize(undoH),tH);
  1626.             HUnlock(undoH);
  1627.             DisposeHandle(undoH);
  1628.             TE32KSetSelect((**tH).selEnd-len,(**tH).selEnd,tH);
  1629.         }
  1630.         (**tH).resetUndo=true;
  1631.     }
  1632. }
  1633.  
  1634. #endif
  1635.  
  1636. void TE32KDelete(TE32KHandle tH)
  1637. {
  1638.     LongRect            updateRect;
  1639.     register long        *theLine,*otherLine,theLineStart,i,delta;
  1640.     long                firstLine,lastLine;
  1641.     Rect                tempRect;
  1642.     RgnHandle            updateRgn;
  1643.     GrafPtr                oldPort;
  1644.     Handle                undoH;
  1645.  
  1646.     if (tH && (**tH).selStart < (**tH).selEnd) {
  1647.         invertSelectRgn(tH);        /*  Deselect */
  1648.         if((**tH).selRgn)
  1649.             SetEmptyRgn((**tH).selRgn);
  1650.             
  1651.         firstLine = indexToLine((**tH).selStart,tH);
  1652.         lastLine = indexToLine((**tH).selEnd,tH);
  1653.         
  1654.         updateRect = (**tH).viewRect;
  1655.         updateRect.top = (**tH).destRect.top + (firstLine + 1) * (**tH).lineHeight;
  1656.         LongRectToRect(&updateRect,&tempRect);
  1657.         
  1658.         GetPort(&oldPort);
  1659.         SetPort((**tH).inPort);
  1660.                 
  1661.         updateRgn = NewRgn();
  1662.         ScrollRect(&tempRect,0,-(**tH).lineHeight * (lastLine - firstLine),updateRgn);
  1663.         tempRect = (**updateRgn).rgnBBox;
  1664.         DisposeRgn(updateRgn);
  1665.         
  1666.         SetPort(oldPort);
  1667.         
  1668.         delta = (**tH).selEnd - (**tH).selStart;
  1669.         
  1670.         HLock((**tH).hText);
  1671.         
  1672. #ifdef __UNDOACTION__
  1673.         if((**tH).undoBuf)
  1674.             DisposeHandle((**tH).undoBuf);
  1675.         undoH=NewHandle(delta);
  1676.         if (MemError() || StripAddress(undoH)==nil) {
  1677.             doMessage(2);
  1678.             undoH=0;
  1679.         } else {
  1680.             HLock(undoH);
  1681.             BlockMove(*((**tH).hText) + (**tH).selStart,*undoH,delta);
  1682.             HUnlock(undoH);
  1683.         }
  1684.         (**tH).undoBuf=undoH;
  1685.         (**tH).undoStart = (**tH).undoEnd = (**tH).selStart;
  1686.         (**tH).resetUndo = false;
  1687.         (**tH).undoDelta = 0;
  1688. #endif
  1689.  
  1690.         if ((**tH).selEnd != (**tH).teLength) {
  1691.             BlockMove(*((**tH).hText) + (**tH).selEnd,*((**tH).hText) + (**tH).selStart,(**tH).teLength - (**tH).selEnd);
  1692.         }
  1693.         HUnlock((**tH).hText);
  1694.         
  1695.         
  1696.         theLine = &((**tH).lineStarts[firstLine + 1]);
  1697.         otherLine = &((**tH).lineStarts[lastLine + 1]);
  1698.         i = (**tH).nLines - lastLine;
  1699.         
  1700.         while (i--) {
  1701.             theLineStart = *(otherLine++);
  1702.             theLineStart -= delta;
  1703.             *(theLine++) = theLineStart;
  1704.         }
  1705.         
  1706.         (**tH).teLength -= delta;
  1707.         (**tH).selEnd = (**tH).selStart;
  1708.         (**tH).nLines -= (lastLine - firstLine);
  1709.         
  1710.         RectToLongRect(&tempRect,&updateRect);
  1711.         TE32KUpdate(&updateRect,tH);    /* update scrolled stuff */
  1712.         
  1713.         updateLine(firstLine,tH,TRUE,0);
  1714.     }
  1715. }
  1716.  
  1717. void TE32KInsert(Ptr textPtr,register long textLength,TE32KHandle tH)
  1718. {
  1719.     register long                *theLine,*otherLine,i,numCRs;
  1720.     long                        firstLine,teLength,maxLineStarts,sizeTE32KHandle, delta;
  1721.     register unsigned char        *charPtr,*charBase;
  1722.     RgnHandle                    updateRgn;
  1723.     Rect                        tempRect;
  1724.     GrafPtr                        oldPort;
  1725.     Handle                        newText;
  1726.  
  1727.     if (tH && textPtr && textLength > 0) {
  1728.         if ((**tH).selStart < (**tH).selEnd) {
  1729.             delta = (**tH).selEnd - (**tH).selStart;
  1730.             invertSelectRgn(tH);        /*  Deselect */
  1731.             if((**tH).selRgn)
  1732.                 SetEmptyRgn((**tH).selRgn);
  1733.         } else
  1734.             delta = 0;
  1735.  
  1736.         if (textLength == 1) {
  1737.             TE32KKey(*((unsigned char *) textPtr),tH,0);
  1738.         } else {
  1739.             firstLine = indexToLine((**tH).selStart,tH);
  1740.             
  1741.             teLength = (**tH).teLength + textLength;
  1742.             
  1743.             if (GetHandleSize((**tH).hText) < teLength) {
  1744.                 SetHandleSize((**tH).hText,teLength + EXTRATEXTBUFF);
  1745.                 
  1746.                 if (MemError() || GetHandleSize((**tH).hText) < teLength + EXTRATEXTBUFF) {
  1747.                     newText=NewHandle(teLength + EXTRATEXTBUFF);
  1748.                     if(!newText) {
  1749.                         doMessage(1);
  1750.                         return;
  1751.                     }
  1752.                     HLock((**tH).hText);
  1753.                     HLock(newText);
  1754.                     
  1755.                     BlockMove(*((**tH).hText),*newText,GetHandleSize((**tH).hText));
  1756.                     
  1757.                     HUnlock((**tH).hText);
  1758.                     HUnlock(newText);
  1759.                     DisposeHandle((**tH).hText);
  1760.                     (**tH).hText=newText;
  1761.                 }
  1762.             }
  1763.             
  1764.             HLock((**tH).hText);
  1765.             
  1766. #ifdef __UNDOACTION__
  1767.  
  1768.             (**tH).undoStart = (**tH).selStart;
  1769.             (**tH).undoEnd = (**tH).selStart + textLength;
  1770.  
  1771. #endif
  1772.             if ((**tH).teLength - (**tH).selStart)
  1773.                 BlockMove(*((**tH).hText) + (**tH).selStart, *((**tH).hText) + (**tH).selStart + textLength, (**tH).teLength - (**tH).selStart);
  1774.             
  1775.             BlockMove(textPtr,*((**tH).hText) + (**tH).selStart,textLength);
  1776.             
  1777.             HUnlock((**tH).hText);
  1778.             
  1779.             i = textLength;
  1780.             numCRs = 0;
  1781.             charPtr = (unsigned char *) textPtr;
  1782.             
  1783.             while (i--) {
  1784.                 if (iseol(*charPtr))
  1785.                     numCRs++;
  1786.                 
  1787.                 charPtr++;
  1788.             }
  1789.             
  1790.             if (numCRs) {
  1791.                 sizeTE32KHandle  = GetHandleSize((Handle) tH);
  1792.                 maxLineStarts = (sizeTE32KHandle - (long) sizeof(TE32KRec))/(long) sizeof(long) - 2;
  1793.                 
  1794.                 if ((**tH).nLines + numCRs >= maxLineStarts) {
  1795.                     sizeTE32KHandle = (long) sizeof(TE32KRec) + (long) sizeof(long)*((**tH).nLines + numCRs + EXTRALINESTARTS);
  1796.                     maxLineStarts = (sizeTE32KHandle - (long) sizeof(TE32KRec))/(long) sizeof(long) - 2;
  1797.                     
  1798.                     SetHandleSize((Handle) tH,sizeTE32KHandle);
  1799.                     
  1800.                     if (MemError()) {
  1801.                         doMessage(1);
  1802.                         return;
  1803.                     }
  1804.                 }
  1805.                 
  1806.                 theLine = &((**tH).lineStarts[(**tH).nLines]);
  1807.                 otherLine = &((**tH).lineStarts[(**tH).nLines + numCRs]);
  1808.                 i = (**tH).nLines - firstLine;
  1809.                 
  1810.                 while (i--)
  1811.                     *(otherLine--) = *(theLine--) + textLength;
  1812.                 
  1813.             /*    charPtr = (unsigned char *) (*((**tH).hText) + (**tH).selStart) + 1;    */
  1814.                 charPtr = (unsigned char *) (*((**tH).hText) + (**tH).selStart) ;
  1815.                 charBase = (unsigned char *) *((**tH).hText);
  1816.                 theLine = &((**tH).lineStarts[firstLine + 1]);
  1817.                 i = numCRs;
  1818.                 
  1819.                 while (i--) {
  1820.                     while (isneol(*charPtr))
  1821.                         charPtr++;
  1822.                     
  1823.                     charPtr++;
  1824.                     
  1825.                     *theLine++ = charPtr - charBase;
  1826.                 }
  1827.                 
  1828.                 LongRectToRect(&((**tH).viewRect),&tempRect);
  1829.                 tempRect.top = (**tH).destRect.top + (firstLine + 1) * (**tH).lineHeight;
  1830.                 
  1831.                 GetPort(&oldPort);
  1832.                 SetPort((**tH).inPort);
  1833.                 
  1834.                 updateRgn = NewRgn();
  1835.                 ScrollRect(&tempRect,0,(**tH).lineHeight * numCRs,updateRgn);
  1836.                 DisposeRgn(updateRgn);
  1837.                 
  1838.                 SetPort(oldPort);
  1839.             } else {
  1840.                 theLine = &((**tH).lineStarts[firstLine + 1]);
  1841.                 i = (**tH).nLines - firstLine;
  1842.                 
  1843.                 while (i--)
  1844.                     *(theLine++) += textLength;
  1845.             }
  1846.             
  1847.             (**tH).teLength = teLength;
  1848.             (**tH).selStart += textLength;
  1849.             (**tH).selEnd = (**tH).selStart;
  1850.             (**tH).nLines += numCRs;
  1851.             
  1852.             do {
  1853.                 updateLine(firstLine,tH,TRUE,0);
  1854.                 
  1855.                 if (numCRs) {
  1856.                     theLine = (**tH).lineStarts;
  1857.                     charPtr = (unsigned char *) *((**tH).hText);
  1858.                     
  1859.                     do {
  1860.                         firstLine++;
  1861.                     } while (firstLine < (**tH).nLines && isneol(charPtr[theLine[firstLine] - 1]));
  1862.                 }
  1863.             } while (numCRs--);
  1864.         }
  1865.     }
  1866. }
  1867.  
  1868. void TE32KPaste(TE32KHandle tH)
  1869. {
  1870.     if (tH && TE32KScrpHandle && TE32KScrpLength > 0) {
  1871.     
  1872.         if ((**tH).selStart < (**tH).selEnd)
  1873.             TE32KDelete( tH);
  1874. #ifdef __UNDOACTION__
  1875.         else {
  1876.             (**tH).resetUndo = false;
  1877.             (**tH).undoStart = (**tH).undoEnd = (**tH).selStart;
  1878.             if((**tH).undoBuf)
  1879.                 DisposeHandle((**tH).undoBuf);
  1880.             (**tH).undoBuf = 0;
  1881.             (**tH).undoDelta = 0;
  1882.         }
  1883. #endif
  1884.         
  1885.         HLock(TE32KScrpHandle);
  1886.         
  1887.         TE32KInsert(*TE32KScrpHandle,TE32KScrpLength,tH);
  1888.         
  1889.         HUnlock(TE32KScrpHandle);
  1890.     }
  1891. }
  1892.  
  1893. Handle    TE32KScrapHandle()
  1894. {
  1895.     return(TE32KScrpHandle);
  1896. }
  1897.  
  1898. long    TE32KGetScrapLen()
  1899. {
  1900.     return(TE32KScrpLength);
  1901. }
  1902.  
  1903. void TE32KSetScrapLen(long newLength)
  1904. {
  1905.     TE32KScrpLength = newLength;
  1906. }
  1907.  
  1908. void TE32KSelView(TE32KHandle tH)
  1909. {    positionView(tH,0); }
  1910.  
  1911. void positionView(TE32KHandle tH, long position)
  1912. {
  1913.     register long    deltaV,deltaH,screenLines,lineHeight,viewTop,viewBot,selPtV,ascent;
  1914.     LongPoint selPt;
  1915.  
  1916.     if (tH) {
  1917.         if ((**tH).selStart != (**tH).selEnd) {
  1918.             TE32KGetPoint((**tH).selStart,&selPt,tH);
  1919.             (**tH).selPoint=selPt;
  1920.         }
  1921.         selPtV = (**tH).selPoint.v;
  1922.         viewTop = (**tH).viewRect.top;
  1923.         viewBot = (**tH).viewRect.bottom;
  1924.         lineHeight = (**tH).lineHeight;
  1925.         ascent = (**tH).fontAscent;
  1926.         screenLines = (viewBot - viewTop) / lineHeight;
  1927.         
  1928.         /*
  1929.             Calculate any lack of registation of whole lines with top of window. 
  1930.             The result, i.e. deltaV, should be zero if everything is well-behaved. 
  1931.         */
  1932.         
  1933.         deltaV = viewTop - (**tH).destRect.top;
  1934.         deltaV -= (deltaV/lineHeight)*lineHeight;
  1935.         
  1936.         /*    DeltaV is always calculated and used */
  1937.         
  1938.         if (selPtV - ascent < viewTop) {
  1939.             deltaV += viewTop-(selPtV-ascent);
  1940.             if(position)
  1941.                 deltaV+=(screenLines/3)*lineHeight;
  1942.         } else if (selPtV > viewBot) {
  1943.             deltaV -= (selPtV-ascent+lineHeight)-(viewTop+screenLines*lineHeight);
  1944.             if(position)
  1945.                 deltaV-=(screenLines*2/3)*lineHeight;
  1946.         }
  1947.         
  1948.         /*============= 1/8/94 ===============
  1949.             DeltaH is not appropiate if we are word wrapping. Cases where a typed 
  1950.             whitespace character (space or tab) exceed the right window boundary
  1951.             are trapped by TE32KKey. 
  1952.         */
  1953.         
  1954.         if((**tH).crOnly) {
  1955.             if ((**tH).selPoint.h <= (**tH).viewRect.left) {
  1956.                 deltaH = (**tH).viewRect.left - (**tH).selPoint.h;
  1957.                 deltaH = (2 + deltaH/(**tH).lineHeight) * (**tH).lineHeight;
  1958.                 
  1959.                 if ((**tH).destRect.left + deltaH > (**tH).viewRect.left)
  1960.                     deltaH = (**tH).viewRect.left - (**tH).destRect.left;
  1961.             } else if ((**tH).selPoint.h > (**tH).viewRect.right) {
  1962.                 deltaH = (**tH).selPoint.h - (**tH).viewRect.right;
  1963.                 deltaH = -(2 + deltaH/(**tH).lineHeight) * (**tH).lineHeight;
  1964.             } else
  1965.                 deltaH = 0;
  1966.         } else
  1967.             deltaH = 0;
  1968.         
  1969.         if (deltaV || deltaH)
  1970.             TE32KScroll(deltaH,deltaV,tH);
  1971.     }
  1972. }
  1973.  
  1974. static Boolean DoDeleteKey(TE32KHandle tH)
  1975. /*  Returns true if doc did change */
  1976. {
  1977.     Rect            tempRect;
  1978.     RgnHandle        updateRgn;
  1979.     short            chWidth;
  1980.     long            firstLine;
  1981.     register short    *theCharWidths;
  1982.     register long    i,*lineStarts,selIndex,*otherLine;
  1983.     LongRect        updateRect;
  1984.     LongPoint        selPt;
  1985.     unsigned char    ch,prevChar;
  1986.     GrafPtr            oldPort;
  1987.  
  1988.     if ((**tH).selStart < (**tH).selEnd) {
  1989.         TE32KDelete(tH);
  1990.         return true;
  1991.     }
  1992.     if ((**tH).selStart > 0) {
  1993.         ch = ((unsigned char *) *((**tH).hText))[(**tH).selStart - 1];
  1994.         
  1995.         if ((**tH).selStart >= 2)
  1996.             prevChar = ((unsigned char *) *((**tH).hText))[(**tH).selStart - 2];
  1997.         else
  1998.             prevChar = '\0';
  1999.         
  2000.         firstLine = indexToLine((**tH).selStart,tH);
  2001.         
  2002. #ifdef __UNDOACTION__
  2003.         if((**tH).resetUndo) {
  2004.             (**tH).resetUndo = false;
  2005.             (**tH).undoStart = (**tH).undoEnd = (**tH).selStart;
  2006.             if((**tH).undoBuf)
  2007.                 DisposeHandle((**tH).undoBuf);
  2008.             (**tH).undoBuf = 0;
  2009.             (**tH).undoDelta = 0;
  2010.         }
  2011.         (**tH).undoEnd--;
  2012.         if((**tH).undoEnd < (**tH).undoStart) {
  2013.             /*    We have deleted past beginning of original selection. Need to
  2014.                 grow the undo buffer backwards. */
  2015.             if((**tH).undoBuf) {
  2016.                 i=GetHandleSize((**tH).undoBuf);
  2017.                 SetHandleSize((**tH).undoBuf,i+1);
  2018.             } else {
  2019.                 (**tH).undoBuf=NewHandle(1);
  2020.                 i=0;
  2021.             }
  2022.             chWidth = (short)MemError();
  2023.             if(chWidth==noErr) {
  2024.                 HLock((**tH).undoBuf);
  2025.                 if(i)
  2026.                     BlockMove(*(**tH).undoBuf,*(**tH).undoBuf+1,i);
  2027.                 *(*(**tH).undoBuf)=ch;
  2028.                 HUnlock((**tH).undoBuf);
  2029.             }
  2030.         }
  2031. #endif
  2032.  
  2033.         HLock((**tH).hText);
  2034.         BlockMove(*((**tH).hText)+(**tH).selStart,*((**tH).hText)+(**tH).selStart-1,(**tH).teLength-(**tH).selEnd);
  2035.         HUnlock((**tH).hText);
  2036.         
  2037.         (**tH).teLength--;
  2038.         (**tH).selStart--;
  2039.         (**tH).selEnd = (**tH).selStart;
  2040.  
  2041.         if (iseol(ch) && 
  2042.             ((**tH).crOnly || (**tH).teLength == (**tH).selStart || iseol(prevChar))) {
  2043.  
  2044.             lineStarts = &((**tH).lineStarts[firstLine]);
  2045.             otherLine = &((**tH).lineStarts[firstLine + 1]);
  2046.             
  2047.             i = (**tH).nLines - firstLine;
  2048.             
  2049.             while (i--) {
  2050.                 selIndex = *(otherLine++);
  2051.                 *(lineStarts++) = --selIndex;
  2052.             }
  2053.             
  2054.             (**tH).nLines--;
  2055.             
  2056.             if (firstLine > 0)
  2057.                 firstLine--;
  2058.             
  2059.             updateRect = (**tH).viewRect;
  2060.             updateRect.top = (**tH).destRect.top + firstLine * (**tH).lineHeight;
  2061.             updateRect.bottom = updateRect.top + (**tH).lineHeight;
  2062.             TE32KUpdate(&updateRect,tH);
  2063.             
  2064.             LongRectToRect(&updateRect,&tempRect);
  2065.             tempRect.top = tempRect.bottom;
  2066.             
  2067.             tempRect.bottom = Clip2Short((**tH).viewRect.bottom);
  2068.             
  2069.             GetPort(&oldPort);
  2070.             SetPort((**tH).inPort);
  2071.         
  2072.             updateRgn = NewRgn();
  2073.             ScrollRect(&tempRect,0,-(**tH).lineHeight,updateRgn);
  2074.             tempRect = (**updateRgn).rgnBBox;
  2075.             DisposeRgn(updateRgn);
  2076.             
  2077.             SetPort(oldPort);
  2078.             
  2079.             TE32KGetPoint((**tH).selStart,&selPt,tH);
  2080.             (**tH).selPoint = selPt;
  2081.             
  2082.             RectToLongRect(&tempRect,&updateRect);
  2083.             
  2084.             mClearCaret(tH);
  2085.         
  2086.             TE32KUpdate(&updateRect,tH);
  2087.             
  2088.         } else {
  2089.         
  2090.             lineStarts = &((**tH).lineStarts[(**tH).nLines]);
  2091.             i = (**tH).nLines - firstLine;
  2092.             
  2093.             if (iseol(ch))
  2094.                 i++;
  2095.             
  2096.             
  2097.             while (i--)
  2098.                 (*(lineStarts--))--;
  2099.             
  2100.             theCharWidths = (**tH).theCharWidths;
  2101.             
  2102.             if (ch == TAB)
  2103.                 chWidth = (**tH).tabWidth;
  2104.             else
  2105.                 chWidth = theCharWidths[ch];
  2106.             
  2107.             if (iseol(ch)) {
  2108.                 firstLine--;
  2109.                 
  2110.                 updateRect.top = (**tH).destRect.top + firstLine * (**tH).lineHeight;
  2111.                 updateRect.bottom = updateRect.top + (**tH).lineHeight;
  2112.                 updateRect.left = (**tH).viewRect.left;
  2113.                 updateRect.right = (**tH).viewRect.right;
  2114.  
  2115.             } else {
  2116.             
  2117.                 updateRect.top = (**tH).destRect.top + firstLine * (**tH).lineHeight;
  2118.                 updateRect.bottom = updateRect.top + (**tH).lineHeight;
  2119.                 updateRect.left = (**tH).selPoint.h - chWidth;
  2120.                 updateRect.right = (**tH).viewRect.right;
  2121.             }
  2122.             
  2123.             mClearCaret(tH);
  2124.             
  2125.             if ((**tH).crOnly)
  2126.                 TE32KUpdate(&updateRect,tH);
  2127.             else 
  2128.                 updateLine(firstLine,tH,TRUE,&updateRect);
  2129.  
  2130.         }
  2131.         return true;
  2132.     }
  2133.     return false;
  2134. }
  2135.  
  2136. static Boolean DoForwardDelete(TE32KHandle tH)
  2137. {
  2138.     if ((**tH).selStart < (**tH).selEnd) {
  2139.         TE32KDelete(tH);
  2140.         return true;
  2141.     }
  2142.     if((**tH).selStart<(**tH).teLength) {
  2143.         (**tH).selStart++;
  2144.         (**tH).selEnd=(**tH).selStart;
  2145.         return DoDeleteKey(tH);
  2146.     }
  2147.     return false;
  2148. }
  2149.  
  2150. static void DoHorizontalArrowKeys(unsigned char ch,TE32KHandle tH,short modifiers)
  2151. {
  2152.     long         thisLine,target;
  2153.     char        *p;
  2154.  
  2155.     if(ch==RIGHTARROW) {
  2156.         target=(TE32KAnchor==(**tH).selEnd)?(**tH).selStart:(**tH).selEnd;
  2157.         if(target<(**tH).teLength) {
  2158.             if(modifiers&cmdKey) {        /* go to end of line, not paragraph */
  2159.                 thisLine=indexToLine(target,tH);
  2160.                 if((thisLine+1)<(**tH).nLines) {
  2161.                     thisLine++;
  2162.                     target=(**tH).lineStarts[thisLine]-1;
  2163.                 } else
  2164.                     target=(**tH).teLength;
  2165.             } else if(modifiers&optionKey) {    /* go to end of word or line */
  2166.                 thisLine=indexToLine(target,tH);
  2167.                 HLock((**tH).hText);
  2168.                 p=(*(**tH).hText)+target;
  2169.                 p++; target++;
  2170.                 while(!isalnum(*p) && target<(**tH).lineStarts[thisLine+1]) { p++; target++; }
  2171.                 while(isalnum(*p) && target<(**tH).lineStarts[thisLine+1]) { p++; target++; }
  2172.                 HUnlock((**tH).hText);
  2173.             } else if((**tH).selStart>=(**tH).selEnd || modifiers&shiftKey)
  2174.                 target++;
  2175.         }
  2176.     } else {
  2177.         target=(TE32KAnchor==(**tH).selStart)?(**tH).selEnd:(**tH).selStart;
  2178.         if(target) {
  2179.             if(modifiers&cmdKey) {
  2180.                 thisLine=indexToLine(target,tH);
  2181.                 target=(**tH).lineStarts[thisLine];
  2182.             } else if(modifiers&optionKey) {
  2183.                 thisLine=indexToLine(target,tH);
  2184.                 if(thisLine>0 && target==(**tH).lineStarts[thisLine])
  2185.                     thisLine--;
  2186.                 HLock((**tH).hText);
  2187.                 p=(*(**tH).hText)+target;
  2188.                 p--;
  2189.                 while(!isalnum(*p) && target>(**tH).lineStarts[thisLine]) { p--; target--; }
  2190.                 while(isalnum(*p) && target>(**tH).lineStarts[thisLine]) { p--; target--; }
  2191.                 HUnlock((**tH).hText);
  2192.             } else if(((**tH).selStart>=(**tH).selEnd) && target || modifiers&shiftKey)
  2193.                 target--;
  2194.         }
  2195.     }
  2196.     if(modifiers&shiftKey) {    /* Extend the selection */
  2197.         if (ch==LEFTARROW) {
  2198.             if(TE32KAnchor==(**tH).selStart) {
  2199.                 if(target>TE32KAnchor)    {            /* Reduce selection */
  2200.                     extendHilite((**tH).selEnd,target,tH);
  2201.                     (**tH).selEnd = target;
  2202.                 } else {                                /* Flip selection to other side of anchor */
  2203.                     TE32KSetSelect(target,TE32KAnchor,tH);
  2204.                     TE32KAnchor=(**tH).selEnd;
  2205.                 }
  2206.             } else {
  2207.                 extendHilite(target,(**tH).selStart,tH);
  2208.                 TE32KAnchor = (**tH).selEnd;
  2209.                 (**tH).selStart = target;
  2210.             }
  2211.         } else if (ch==RIGHTARROW) {
  2212.             if(TE32KAnchor==(**tH).selEnd) {
  2213.                 if(target<TE32KAnchor) {
  2214.                     extendHilite(target,(**tH).selStart,tH);
  2215.                     (**tH).selStart = target;
  2216.                 } else {
  2217.                     TE32KSetSelect(TE32KAnchor,target,tH);
  2218.                     TE32KAnchor = (**tH).selStart;
  2219.                 }
  2220.             } else {
  2221.                 extendHilite((**tH).selEnd,target,tH);                /*  Extend down */
  2222.                 TE32KAnchor = (**tH).selStart;
  2223.                 (**tH).selEnd = target;
  2224.             }
  2225.         }
  2226.     } else {
  2227.         TE32KSetSelect(target,target,tH);
  2228.         TE32KAnchor = -1;
  2229.     }
  2230.     TE32KHPos = -1;
  2231. }
  2232.  
  2233. static void DoVerticalArrowKeys(unsigned char ch,TE32KHandle tH,short modifiers)
  2234. {
  2235.     LongPoint        selPt,tempPt1,tempPt2;
  2236.     long            firstLine,selIndex;
  2237.  
  2238.     if(modifiers&cmdKey && modifiers&optionKey) {
  2239.         TE32KHPos = -1;
  2240.         if(ch==UPARROW) {
  2241.             if(modifiers&shiftKey) {
  2242.                 TE32KSetSelect(0,(**tH).selEnd,tH);
  2243.                 TE32KAnchor = (**tH).selEnd;
  2244.             } else 
  2245.                 TE32KSetSelect(0,0,tH);
  2246.             return;
  2247.         }
  2248.         if(ch==DOWNARROW) {
  2249.             if(modifiers&shiftKey) {
  2250.                 TE32KSetSelect((**tH).selStart,(**tH).teLength,tH);
  2251.                 TE32KAnchor = (**tH).selStart;
  2252.             } else 
  2253.                 TE32KSetSelect((**tH).teLength,(**tH).teLength,tH);                
  2254.             return;
  2255.         }
  2256.     }
  2257.     
  2258.     mClearCaret(tH);
  2259.     
  2260.     if(modifiers&shiftKey) {    /*  Extend the selection */
  2261.         if(ch==UPARROW) {
  2262.             firstLine = indexToLine((**tH).selStart,tH);
  2263.             if(firstLine > 0) {
  2264.                 if(TE32KAnchor==(**tH).selStart) {
  2265.                     TE32KGetPoint((**tH).selEnd,&selPt,tH);
  2266.                     selPt.v -= (**tH).lineHeight;
  2267.                     
  2268.                     if(TE32KHPos==-1) 
  2269.                         TE32KHPos=selPt.h;
  2270.                     else
  2271.                         selPt.h=TE32KHPos;
  2272.                         
  2273.                     selIndex = TE32KGetOffset(&selPt,tH);
  2274.                     if(selIndex>TE32KAnchor)    {            /* Reduce selection */
  2275.                         extendHilite((**tH).selEnd,selIndex,tH);
  2276.                         (**tH).selEnd = selIndex;
  2277.                     } else {                                /* Flip selection to other side of anchor */
  2278.                         TE32KSetSelect(selIndex,TE32KAnchor,tH);
  2279.                         TE32KAnchor=(**tH).selEnd;
  2280.                     }
  2281.                 } else {
  2282.                     TE32KGetPoint((**tH).selStart,&selPt,tH);
  2283.                     selPt.v -= (**tH).lineHeight;
  2284.                     
  2285.                     if(TE32KHPos==-1) 
  2286.                         TE32KHPos=selPt.h;
  2287.                     else
  2288.                         selPt.h=TE32KHPos;
  2289.                         
  2290.                     selIndex = TE32KGetOffset(&selPt,tH);
  2291.                     extendHilite(selIndex,(**tH).selStart,tH);
  2292.                     TE32KAnchor = (**tH).selEnd;
  2293.                     (**tH).selStart = selIndex;
  2294.                 }
  2295.             }
  2296.         } else if (ch==DOWNARROW) {
  2297.             firstLine = indexToLine((**tH).selEnd,tH);
  2298.             if (firstLine < (**tH).nLines - 1) {
  2299.                 if(TE32KAnchor==(**tH).selEnd) {
  2300.                     TE32KGetPoint((**tH).selStart,&selPt,tH);
  2301.                     selPt.v += (**tH).lineHeight;
  2302.                     
  2303.                     if(TE32KHPos==-1) 
  2304.                         TE32KHPos=selPt.h;
  2305.                     else
  2306.                         selPt.h=TE32KHPos;
  2307.                         
  2308.                     selIndex = TE32KGetOffset(&selPt,tH);
  2309.                     if(selIndex<TE32KAnchor) {
  2310.                         extendHilite(selIndex,(**tH).selStart,tH);
  2311.                         (**tH).selStart = selIndex;
  2312.                     } else {
  2313.                         TE32KSetSelect(TE32KAnchor,selIndex,tH);
  2314.                         TE32KAnchor = (**tH).selStart;
  2315.                     }
  2316.                 } else {
  2317.                     TE32KGetPoint((**tH).selEnd,&selPt,tH);
  2318.                     selPt.v += (**tH).lineHeight;
  2319.                     
  2320.                     if(TE32KHPos==-1) 
  2321.                         TE32KHPos=selPt.h;
  2322.                     else
  2323.                         selPt.h=TE32KHPos;
  2324.                         
  2325.                     selIndex = TE32KGetOffset(&selPt,tH);
  2326.                     extendHilite((**tH).selEnd,selIndex,tH);                /*  Extend down */
  2327.                     TE32KAnchor = (**tH).selStart;
  2328.                     (**tH).selEnd = selIndex;
  2329.                 }
  2330.             }
  2331.         }
  2332.     } else {
  2333.     
  2334.         TE32KAnchor = -1;
  2335.         
  2336.         if ((**tH).selStart < (**tH).selEnd)
  2337.             invertSelectRgn(tH);                            /*  remove selection */
  2338.  
  2339.         if ((**tH).selStart < (**tH).selEnd) {                
  2340.             if (ch == DOWNARROW)
  2341.                 TE32KGetPoint((**tH).selEnd,&selPt,tH);
  2342.             else
  2343.                 TE32KGetPoint((**tH).selStart,&selPt,tH);
  2344.                                     
  2345.             (**tH).selPoint = selPt;
  2346.         }
  2347.         
  2348.         selPt = (**tH).selPoint;
  2349.             
  2350.         if(TE32KHPos==-1) 
  2351.             TE32KHPos=selPt.h;
  2352.         else
  2353.             selPt.h=TE32KHPos;
  2354.             
  2355.         if (ch==UPARROW) {
  2356.  
  2357.             firstLine = indexToLine((**tH).selStart,tH);
  2358.             
  2359.             if (firstLine > 0) {
  2360.                 selPt.v -= (**tH).lineHeight;
  2361.                 (**tH).selStart = TE32KGetOffset(&selPt,tH);
  2362.                 (**tH).selEnd = (**tH).selStart;
  2363.                 firstLine = indexToLine((**tH).selStart,tH);
  2364.                 
  2365.                 if (!(**tH).crOnly && (**tH).selStart == (**tH).lineStarts[firstLine]) {
  2366.                     (**tH).clikStuff = FALSE;
  2367.                     TE32KGetPoint((**tH).selStart,&tempPt1,tH);
  2368.                     
  2369.                     (**tH).clikStuff = TRUE;
  2370.                     TE32KGetPoint((**tH).selStart,&tempPt2,tH);
  2371.                     
  2372.                     if ((selPt.h - tempPt1.h)*(selPt.h - tempPt1.h) + (selPt.v - tempPt1.v)*(selPt.v - tempPt1.v) <
  2373.                         (selPt.h - tempPt2.h)*(selPt.h - tempPt2.h) + (selPt.v - tempPt2.v)*(selPt.v - tempPt2.v))
  2374.                             (**tH).selPoint = tempPt1;
  2375.                     else
  2376.                             (**tH).selPoint = tempPt2;
  2377.                     
  2378.                     return;
  2379.                 } else {
  2380.                     (**tH).clikStuff = FALSE;
  2381.                     TE32KGetPoint((**tH).selStart,&selPt,tH);
  2382.                     (**tH).selPoint = selPt;
  2383.                 }
  2384.             }
  2385.         } else {
  2386.  
  2387.             firstLine = indexToLine((**tH).selStart,tH);
  2388.             
  2389.             if (firstLine < (**tH).nLines) {
  2390.                 selPt.v += (**tH).lineHeight;
  2391.                 (**tH).selEnd = TE32KGetOffset(&selPt,tH);
  2392.                 (**tH).selStart = (**tH).selEnd;
  2393.                 firstLine = indexToLine((**tH).selEnd,tH);
  2394.                 
  2395.                 if (!(**tH).crOnly && (**tH).selStart == (**tH).lineStarts[firstLine]) {
  2396.                     (**tH).clikStuff = FALSE;
  2397.                     TE32KGetPoint((**tH).selStart,&tempPt1,tH);
  2398.                     
  2399.                     (**tH).clikStuff = TRUE;
  2400.                     TE32KGetPoint((**tH).selStart,&tempPt2,tH);
  2401.                     
  2402.                     if ((selPt.h - tempPt1.h)*(selPt.h - tempPt1.h) + (selPt.v - tempPt1.v)*(selPt.v - tempPt1.v) <
  2403.                         (selPt.h - tempPt2.h)*(selPt.h - tempPt2.h) + (selPt.v - tempPt2.v)*(selPt.v - tempPt2.v))
  2404.                             (**tH).selPoint = tempPt1;
  2405.                     else
  2406.                             (**tH).selPoint = tempPt2;
  2407.                     
  2408.                     return;
  2409.                 } else {
  2410.                     (**tH).clikStuff = FALSE;
  2411.                     TE32KGetPoint((**tH).selEnd,&selPt,tH);
  2412.                     (**tH).selPoint = selPt;
  2413.                 }
  2414.             }
  2415.         }
  2416.         
  2417.         (**tH).selEnd = (**tH).selStart;
  2418.         xorCaret(tH);
  2419.     }
  2420. }
  2421.  
  2422. static    DoNormalChar(unsigned char ch,TE32KHandle tH)
  2423. {
  2424.     Rect            tempRect;
  2425.     RgnHandle        updateRgn;
  2426.     short            chWidth,destLeftSide;
  2427.     register short    *theCharWidths;
  2428.     long            teLength,thisLine;
  2429.     register long    i,*lineStarts,delta;
  2430.     LongPoint        selPt;
  2431.     unsigned char    prevChar;
  2432.     GrafPtr            oldPort;
  2433.     short            oldFont,oldFace,oldSize,oldMode;
  2434.     
  2435.     teLength = (**tH).teLength + 1;
  2436.     
  2437.     if (GetHandleSize((**tH).hText) < teLength) {
  2438.         SetHandleSize((**tH).hText,teLength + EXTRATEXTBUFF);
  2439.         
  2440.         if (MemError() || GetHandleSize((**tH).hText) < teLength) {
  2441.             doMessage(1);
  2442.             return;
  2443.         }
  2444.     }
  2445.     
  2446.     mClearCaret(tH);
  2447.     
  2448.     selPt = (**tH).selPoint;
  2449.     
  2450. /*    selPt.h--;    */
  2451.     
  2452.     thisLine = indexToLine((**tH).selStart,tH);
  2453.     if ((**tH).selStart > 0)
  2454.         prevChar = ((unsigned char *) *(**tH).hText)[(**tH).lineStarts[thisLine] - 1];
  2455.     else
  2456.         prevChar = '\n';
  2457.     
  2458.     /*
  2459.         We will draw the character unless we are wordwrapping and the character is a 
  2460.         space at the end of a line. 
  2461.     */
  2462.     
  2463.     if ((**tH).crOnly || iseol(prevChar) ||
  2464.             !(ch == ' ' && ((**tH).selStart == (**tH).lineStarts[thisLine]))) {
  2465.         
  2466.         if((**tH).selStart == (**tH).lineStarts[thisLine]) {
  2467.             TE32KGetPoint((**tH).selStart,&selPt,tH);
  2468. /*            selPt.h--;    */
  2469.         }
  2470.             
  2471.         tempRect.left = Clip2Short(selPt.h);
  2472.         tempRect.right = Clip2Short((**tH).viewRect.right);
  2473.         
  2474.         selPt.v -= (**tH).fontAscent;
  2475.         tempRect.top = Clip2Short(selPt.v);
  2476.         
  2477.         tempRect.bottom = tempRect.top + (**tH).lineHeight;
  2478.         
  2479.         GetPort(&oldPort);
  2480.         SetPort((**tH).inPort);
  2481.         
  2482.         oldFont = ((**tH).inPort)->txFont;
  2483.         oldFace = ((**tH).inPort)->txFace;
  2484.         oldSize = ((**tH).inPort)->txSize;
  2485.         oldMode = ((**tH).inPort)->txMode;
  2486.         
  2487.         TextFont((**tH).txFont);
  2488.         TextFace((**tH).txFace);
  2489.         TextSize((**tH).txSize);
  2490.         TextMode((**tH).txMode);
  2491.         
  2492.         theCharWidths = (**tH).theCharWidths;
  2493.         
  2494.         if (ch == TAB) {
  2495.             destLeftSide = (**tH).destRect.left + 1;
  2496.             delta = (**tH).tabWidth;
  2497.             chWidth = (destLeftSide + ((tempRect.left  - destLeftSide + delta)/delta)*delta) - tempRect.left;
  2498.         } else 
  2499.             chWidth = theCharWidths[ch];
  2500.         
  2501.         if (tempRect.left < tempRect.right) {    
  2502.             updateRgn = NewRgn();
  2503.             ScrollRect(&tempRect,chWidth,0,updateRgn);
  2504.             
  2505.             if (tempRect.left + chWidth > tempRect.right)
  2506.                 ClipRect(&tempRect);
  2507.             
  2508.             MoveTo(tempRect.left,tempRect.top + (**tH).fontAscent);
  2509.             if((**tH).showInvisibles) {
  2510.                 if(isgraph(ch))
  2511.                     DrawChar(ch);
  2512.                 else if(ch==TAB)
  2513.                     DrawChar('Δ');
  2514.                 else if(ch==' ')
  2515.                     DrawChar('◊');
  2516.                 else if(ch=='\n')
  2517.                     DrawChar('¬');
  2518.                 else if(ch<0x20)
  2519.                     DrawChar('¿');
  2520.                 else 
  2521.                     DrawChar(ch);
  2522.             
  2523.             } else if (ch != TAB)
  2524.                 DrawChar(ch);
  2525.             
  2526.             if (tempRect.left + chWidth > tempRect.right) {
  2527.                 tempRect.left = -32768;
  2528.                 tempRect.top = -32768;
  2529.                 tempRect.right = 32767;
  2530.                 tempRect.bottom = 32767;
  2531.                 ClipRect(&tempRect);
  2532.             }
  2533.             
  2534.             DisposeRgn(updateRgn);
  2535.         }
  2536.         
  2537.         TextFont(oldFont);
  2538.         TextFace(oldFace);
  2539.         TextSize(oldSize);
  2540.         TextMode(oldMode);
  2541.         
  2542.         SetPort(oldPort);
  2543.     }
  2544.     
  2545.     HLock((**tH).hText);
  2546.     BlockMove(*((**tH).hText) + (**tH).selStart,*((**tH).hText) + (**tH).selStart + 1,(**tH).teLength - (**tH).selStart);
  2547.     HUnlock((**tH).hText);
  2548.     
  2549.     ((unsigned char *) *((**tH).hText))[(**tH).selStart] = ch;
  2550.     
  2551.     lineStarts = &((**tH).lineStarts[(**tH).nLines]);
  2552.     i = (**tH).nLines - thisLine;
  2553.     
  2554.     if (!(**tH).crOnly && isneol(prevChar) && ch == ' ' && (**tH).selStart == (**tH).lineStarts[thisLine])
  2555.         i++;
  2556.     
  2557.     while (i--)
  2558.         (*(lineStarts--))++;
  2559.     
  2560. #ifdef __UNDOACTION__
  2561.  
  2562.     if((**tH).resetUndo) {
  2563.         (**tH).resetUndo = false;
  2564.         (**tH).undoStart = (**tH).undoEnd = (**tH).selStart;
  2565.         if((**tH).undoBuf)
  2566.             DisposeHandle((**tH).undoBuf);
  2567.         (**tH).undoBuf = 0;
  2568.         (**tH).undoDelta = 0;
  2569.     }
  2570.     if((**tH).undoEnd<(**tH).undoStart)        /* added a character after a series of deletes */
  2571.         (**tH).undoStart=(**tH).undoEnd;
  2572.         
  2573.     (**tH).undoEnd++;
  2574.         
  2575. #endif
  2576.  
  2577.     (**tH).teLength++;
  2578.     (**tH).selStart++;
  2579.     (**tH).selEnd = (**tH).selStart;
  2580.     (**tH).selPoint.h += (long) chWidth;
  2581.     
  2582. /*    if (!(**tH).crOnly && !isspace(ch)) */
  2583.     if (!(**tH).crOnly)
  2584.         updateLine(thisLine,tH,FALSE,0);
  2585.     
  2586.     xorCaret(tH);
  2587. }
  2588.  
  2589. static    DoReturnChar(TE32KHandle tH)
  2590. {
  2591.     Rect            tempRect;
  2592.     RgnHandle        updateRgn;
  2593.     long            teLength,firstLine,lastLine,deltaLines,numAffected,tempFirstLine;
  2594.     register long    cnt,*lineStarts,selIndex,*otherLine;
  2595.     long            indentCnt=0,leadingCnt=0,indent;
  2596.     LongPoint        selPt;
  2597.     LongRect        updateRect;
  2598.     unsigned char    doWrap,*p;
  2599.     GrafPtr            oldPort;
  2600.     Handle            undoH;
  2601.  
  2602.     teLength = GetHandleSize((Handle) tH);
  2603.     lastLine  = (teLength - (long) sizeof(TE32KRec))/(long) sizeof(long) - 2;
  2604.     
  2605.     if ((**tH).nLines + 1 >= lastLine) {
  2606.         teLength = (long) sizeof(TE32KRec) + (long) sizeof(long)*((**tH).nLines + 1 + EXTRALINESTARTS);
  2607.         
  2608.         SetHandleSize((Handle) tH,teLength);
  2609.         
  2610.         if (MemError()  || GetHandleSize((Handle)tH) < teLength) {
  2611.             doMessage(1);
  2612.             return;
  2613.         }
  2614.     }
  2615.         
  2616.     firstLine = indexToLine((**tH).selStart,tH);
  2617.     
  2618.     mClearCaret(tH);
  2619.  
  2620.     if ((**tH).autoIndent && firstLine > 0) {
  2621.         HLock((**tH).hText);
  2622.         
  2623.         if((**tH).crOnly) 
  2624.             indent = (**tH).lineStarts[firstLine];
  2625.         else {
  2626.             tempFirstLine = indexToParagraph((**tH).selStart,tH);
  2627.             indent = (**tH).lineStarts[tempFirstLine];
  2628.         }
  2629.             
  2630.         p=((unsigned char *) *(**tH).hText)+indent;
  2631.         while(*p==' ' || *p==TAB) { p++; indentCnt++; }
  2632.         p=((unsigned char *) *(**tH).hText)+(**tH).selStart;
  2633.         while(*p==' ' || *p==TAB) { p++; leadingCnt++; }
  2634.         
  2635. #ifdef __UNDOACTION__
  2636.         if(leadingCnt) {
  2637.             if((**tH).undoBuf)
  2638.                 DisposeHandle((**tH).undoBuf);
  2639.             undoH=NewHandle(leadingCnt);
  2640.             if (MemError() || StripAddress(undoH)==nil) {
  2641.                 doMessage(2);
  2642.                 undoH=0;
  2643.             } else {
  2644.                 HLock(undoH);
  2645.                 BlockMove(*((**tH).hText) + (**tH).selStart,*undoH,leadingCnt);
  2646.                 HUnlock(undoH);
  2647.             }
  2648.             (**tH).undoBuf=undoH;
  2649.             (**tH).undoStart = (**tH).undoEnd = (**tH).selStart;
  2650.             (**tH).resetUndo = false;
  2651.             (**tH).undoDelta = 0;
  2652.         }
  2653. #endif
  2654.  
  2655.         teLength = (**tH).teLength + indentCnt - leadingCnt + 1;
  2656.         
  2657.         if (GetHandleSize((**tH).hText) < teLength) {
  2658.         
  2659.             HUnlock((**tH).hText);
  2660.             SetHandleSize((**tH).hText,teLength + EXTRATEXTBUFF);
  2661.             
  2662.             if (MemError() || GetHandleSize((**tH).hText) < teLength) {
  2663.                 doMessage(1);
  2664.                 return;
  2665.             }
  2666.             HLock((**tH).hText);
  2667.         }
  2668.         BlockMove(*((**tH).hText) + (**tH).selStart + leadingCnt,
  2669.                 *((**tH).hText) + (**tH).selStart + indentCnt + 1,
  2670.                 (**tH).teLength - (**tH).selStart - leadingCnt);
  2671.         p=((unsigned char *) *(**tH).hText)+indent; 
  2672.         BlockMove(p,*((**tH).hText) + (**tH).selStart + 1,indentCnt);
  2673.         ((unsigned char *) *((**tH).hText))[(**tH).selStart] = RETURN;
  2674.         
  2675.         HUnlock((**tH).hText);
  2676.         
  2677.     } else {
  2678.         teLength = (**tH).teLength + 1;
  2679.         
  2680.         if (GetHandleSize((**tH).hText) < teLength) {
  2681.             SetHandleSize((**tH).hText,teLength + EXTRATEXTBUFF);
  2682.             
  2683.             if (MemError() || GetHandleSize((**tH).hText) < teLength) {
  2684.                 doMessage(1);
  2685.                 return;
  2686.             }
  2687.         }
  2688.         HLock((**tH).hText);
  2689.         BlockMove(*((**tH).hText) + (**tH).selStart,*((**tH).hText) + (**tH).selStart + 1,(**tH).teLength - (**tH).selStart);
  2690.         HUnlock((**tH).hText);
  2691.         
  2692.         ((unsigned char *) *((**tH).hText))[(**tH).selStart] = RETURN;
  2693.     }
  2694.     
  2695.     lineStarts = &((**tH).lineStarts[(**tH).nLines]);
  2696.     otherLine = &((**tH).lineStarts[(**tH).nLines + 1]);
  2697.     cnt = (**tH).nLines - firstLine;
  2698.         
  2699.     if(indentCnt-leadingCnt) {
  2700.         while (cnt--) {
  2701.             selIndex = *(lineStarts--);
  2702.             *(otherLine--) = (selIndex+=(indentCnt-leadingCnt+1));
  2703.         }
  2704.     } else {
  2705.         while (cnt--) {
  2706.             selIndex = *(lineStarts--);
  2707.             *(otherLine--) = ++selIndex;
  2708.         }
  2709.     }
  2710.     
  2711.     (**tH).lineStarts[firstLine + 1] = (**tH).selStart + 1;
  2712.     
  2713. #ifdef __UNDOACTION__
  2714.  
  2715.     if((**tH).resetUndo) {
  2716.         (**tH).resetUndo = false;
  2717.         (**tH).undoStart = (**tH).undoEnd = (**tH).selStart;
  2718.         if((**tH).undoBuf)
  2719.             DisposeHandle((**tH).undoBuf);
  2720.         (**tH).undoBuf = 0;
  2721.         (**tH).undoDelta = 0;
  2722.     }
  2723.     if((**tH).undoEnd<(**tH).undoStart)        /* added a character after a series of deletes */
  2724.         (**tH).undoStart=(**tH).undoEnd;
  2725.         
  2726.     (**tH).undoEnd+=(indentCnt+1);
  2727.     
  2728. #endif
  2729.  
  2730.     (**tH).nLines++;
  2731.     (**tH).teLength+=(indentCnt-leadingCnt+1);
  2732.     (**tH).selStart+=(indentCnt+1);
  2733.     (**tH).selEnd = (**tH).selStart;
  2734.     
  2735.     LongRectToRect(&((**tH).viewRect),&tempRect);
  2736.     
  2737.     selPt = (**tH).selPoint;
  2738.     selPt.v -= (**tH).fontAscent;
  2739.     selPt.v += (**tH).lineHeight;
  2740.     
  2741.     tempRect.top = Clip2Short(selPt.v);
  2742.     
  2743.     GetPort(&oldPort);
  2744.     SetPort((**tH).inPort);
  2745.             
  2746.     updateRgn = NewRgn();
  2747.     ScrollRect(&tempRect,0,(**tH).lineHeight,updateRgn);
  2748.     DisposeRgn(updateRgn);
  2749.     
  2750.     SetPort(oldPort);
  2751.     
  2752.     if (!(**tH).crOnly) {
  2753.         doWrap = FALSE;
  2754.         tempFirstLine = firstLine;
  2755.         
  2756.         if (tempFirstLine > 0 && LineEndIndex(tempFirstLine - 1,tH) != (**tH).lineStarts[tempFirstLine]) {
  2757.             doWrap = TRUE;
  2758.             tempFirstLine--;
  2759.         } else if (LineEndIndex(tempFirstLine,tH) != (**tH).lineStarts[tempFirstLine + 1])
  2760.             doWrap = TRUE;
  2761.         
  2762.         
  2763.         if (doWrap) {
  2764.             CalParagraph(tempFirstLine,tH,&deltaLines,&numAffected);
  2765.             
  2766.             if (deltaLines == 0) {
  2767.                 updateRect = (**tH).viewRect;
  2768.                 updateRect.top = (**tH).destRect.top + tempFirstLine * (**tH).lineHeight;
  2769.                 updateRect.bottom = updateRect.top + (**tH).lineHeight * numAffected;
  2770.             } else if (deltaLines > 0) {
  2771.             
  2772.                 firstLine += deltaLines;
  2773.                 
  2774.                 LongRectToRect(&((**tH).viewRect),&tempRect);
  2775.                 tempRect.top = (**tH).destRect.top + (tempFirstLine + numAffected - deltaLines) * (**tH).lineHeight;
  2776.                 
  2777.                 GetPort(&oldPort);
  2778.                 SetPort((**tH).inPort);
  2779.                 
  2780.                 updateRgn = NewRgn();
  2781.                 ScrollRect(&tempRect,0,(**tH).lineHeight * deltaLines,updateRgn);
  2782.                 DisposeRgn(updateRgn);
  2783.                 
  2784.                 SetPort(oldPort);
  2785.                 
  2786.                 updateRect = (**tH).viewRect;
  2787.                 updateRect.top = (**tH).destRect.top + tempFirstLine * (**tH).lineHeight;
  2788.                 updateRect.bottom = updateRect.top + (**tH).lineHeight * numAffected;
  2789.             } else {
  2790.                 firstLine += deltaLines;
  2791.                 
  2792.                 LongRectToRect(&((**tH).viewRect),&tempRect);
  2793.                 tempRect.top = (**tH).destRect.top + (tempFirstLine - 1 + numAffected) * (**tH).lineHeight;
  2794.                 
  2795.                 GetPort(&oldPort);
  2796.                 SetPort((**tH).inPort);
  2797.     
  2798.                 updateRgn = NewRgn();
  2799.                 ScrollRect(&tempRect,0,(**tH).lineHeight * deltaLines,updateRgn);
  2800.                 DisposeRgn(updateRgn);
  2801.                 
  2802.                 SetPort(oldPort);
  2803.                 
  2804.                 updateRect = (**tH).viewRect;
  2805.                 updateRect.top = (**tH).destRect.top + tempFirstLine * (**tH).lineHeight;
  2806.                 updateRect.bottom = updateRect.top + (**tH).lineHeight * numAffected;
  2807.             }
  2808.             
  2809.             TE32KUpdate(&updateRect,tH);
  2810.         }
  2811.         
  2812.         firstLine++;
  2813.         
  2814.         CalParagraph(firstLine,tH,&deltaLines,&numAffected);
  2815.         
  2816.         if (deltaLines > 0) {
  2817.             LongRectToRect(&((**tH).viewRect),&tempRect);
  2818.             tempRect.top = (**tH).destRect.top + (firstLine + numAffected - deltaLines) * (**tH).lineHeight;
  2819.             
  2820.             GetPort(&oldPort);
  2821.             SetPort((**tH).inPort);
  2822.     
  2823.             updateRgn = NewRgn();
  2824.             ScrollRect(&tempRect,0,(**tH).lineHeight * deltaLines,updateRgn);
  2825.             DisposeRgn(updateRgn);
  2826.             
  2827.             SetPort(oldPort);
  2828.         } else if (deltaLines < 0) {
  2829.             LongRectToRect(&((**tH).viewRect),&tempRect);
  2830.             tempRect.top = (**tH).destRect.top + (firstLine - 1 + numAffected) * (**tH).lineHeight;
  2831.             
  2832.             GetPort(&oldPort);
  2833.             SetPort((**tH).inPort);
  2834.     
  2835.             updateRgn = NewRgn();
  2836.             ScrollRect(&tempRect,0,(**tH).lineHeight * deltaLines,updateRgn);
  2837.             DisposeRgn(updateRgn);
  2838.             
  2839.             SetPort(oldPort);
  2840.         }
  2841.         
  2842.         updateRect = (**tH).viewRect;
  2843.         updateRect.top = (**tH).destRect.top + (firstLine - 1) * (**tH).lineHeight;
  2844.         updateRect.bottom = updateRect.top + (**tH).lineHeight * (numAffected + 1);
  2845.         
  2846.         mClearCaret(tH);
  2847.         
  2848.         TE32KUpdate(&updateRect,tH);
  2849.         
  2850.         TE32KGetPoint((**tH).selStart,&selPt,tH);
  2851.         (**tH).selPoint = selPt;
  2852.     } else {
  2853.         if ((**tH).nLines - firstLine >= 2 && 
  2854.             (**tH).lineStarts[firstLine+1]+1 < (**tH).lineStarts[firstLine + 2]) {
  2855.             updateRect = (**tH).viewRect;
  2856.             TE32KGetPoint((**tH).selStart,&selPt,tH);
  2857.             (**tH).selPoint = selPt;
  2858.             updateRect.top = (**tH).destRect.top + firstLine * (**tH).lineHeight;
  2859.             updateRect.bottom = updateRect.top + (**tH).lineHeight + (**tH).lineHeight;
  2860.             TE32KUpdate(&updateRect,tH);
  2861.         } else if((**tH).showInvisibles) {
  2862.             GetPort(&oldPort);
  2863.             SetPort((**tH).inPort);
  2864.             selPt = (**tH).selPoint;
  2865.             MoveTo(selPt.h,selPt.v);
  2866.             DrawChar('¬');
  2867.             
  2868.             TE32KGetPoint((**tH).selStart-indentCnt,&selPt,tH);
  2869.             if((**tH).selStart<(**tH).teLength) {
  2870.                 MoveTo(selPt.h,selPt.v);
  2871.                 DrawChar('¬');
  2872.             }
  2873.             TE32KGetPoint((**tH).selStart,&selPt,tH);
  2874.             (**tH).selPoint = selPt;
  2875.             SetPort(oldPort);
  2876.             xorCaret(tH);
  2877.         } else {
  2878.             TE32KGetPoint((**tH).selStart,&selPt,tH);
  2879.             (**tH).selPoint = selPt;
  2880.             xorCaret(tH);
  2881.         }
  2882.     }
  2883. }
  2884.  
  2885. Boolean TE32KKey(unsigned char ch,TE32KHandle tH,short modifiers)
  2886. {
  2887.     Boolean ret=true;
  2888.     
  2889.     if (tH && (**tH).active) {
  2890.         ObscureCursor();
  2891.         
  2892.         if (ch == DELETE)
  2893.             DoDeleteKey(tH);
  2894.         else if(ch == 0x7F)
  2895.             DoForwardDelete(tH);
  2896.         else if (ch==LEFTARROW || ch==RIGHTARROW) {
  2897.             DoHorizontalArrowKeys(ch,tH,modifiers);
  2898.             ret=false;
  2899.         } else if (ch==UPARROW || ch==DOWNARROW) {
  2900.             DoVerticalArrowKeys(ch,tH,modifiers);
  2901.             ret=false;
  2902.         } else {
  2903.             if ((**tH).selStart < (**tH).selEnd)     /* overtype selection */
  2904.                 TE32KDelete(tH);
  2905.  
  2906.             if (ch==RETURN)
  2907.                 DoReturnChar(tH);
  2908.             else if (ch == ENTER) {
  2909.                 ch = RETURN;
  2910.                  DoReturnChar(tH);
  2911.             } else
  2912.                 DoNormalChar(ch,tH);
  2913.         }
  2914.         
  2915.         if ((**tH).selStart == (**tH).selEnd && !(**tH).caretState)
  2916.             xorCaret(tH);
  2917.             
  2918.         return ret;
  2919.     }
  2920.     return false;
  2921. }
  2922.  
  2923. static long paraLines(long firstLine, TE32KHandle tH)
  2924. {
  2925.     long                    lastLine,nLines;
  2926.     register unsigned char    *charBase;
  2927.     register long            *lineStarts;
  2928.  
  2929.     if ((**tH).crOnly)
  2930.         return(1);
  2931.     
  2932.     lastLine = firstLine + 1;
  2933.     nLines = (**tH).nLines;
  2934.     charBase = (unsigned char    *) *((**tH).hText);
  2935.     lineStarts = &((**tH).lineStarts[lastLine]);
  2936.     
  2937.     while (lastLine < nLines && isneol(charBase[*lineStarts - 1])) {
  2938.         lastLine++;
  2939.         lineStarts++;
  2940.     }
  2941.     
  2942.     return(lastLine - firstLine);
  2943. }
  2944.  
  2945. /*-----------------------------------------------------------------------
  2946.     LineEndIndex returns the index of the last character in a line. This
  2947.     is the critical word wrap routine. 
  2948. ------------------------------------------------------------------------*/
  2949.  
  2950. static long    LineEndIndex(long thisLine,TE32KHandle tH)
  2951. {
  2952.     register unsigned char    *charPtr;
  2953.     register long            charCount,tabWidth;
  2954.     register short            *theCharWidths,maxLineWidth,lineWidth;
  2955.     register unsigned char    ch;
  2956.     Boolean                    atLineEnd,wrapToLength;
  2957.     unsigned char            *charBase;
  2958.     Point                    cursorPt;
  2959.     short                    rightSide,destLeftSide;
  2960.     short                    lineStatus;
  2961.     unsigned char            *oldCharPtr;
  2962.     long                    maxRewind;
  2963.     
  2964.     if ((**tH).crOnly)
  2965.         return((**tH).lineStarts[thisLine + 1]);
  2966.     
  2967.     wrapToLength = (**tH).wrapToLength;
  2968.     maxLineWidth = (wrapToLength)? (**tH).maxLineWidth : 32767 ;
  2969.  
  2970.     charBase = (unsigned char *) *((**tH).hText);
  2971.     charPtr = charBase + (**tH).lineStarts[thisLine];
  2972.     charCount = (**tH).teLength - (**tH).lineStarts[thisLine];
  2973.     
  2974.  
  2975.     if (charCount > (**tH).teLength)
  2976.         charCount = (**tH).teLength;
  2977.     
  2978.     lineStatus = 0;
  2979.     lineWidth = 0;
  2980.     
  2981.     if (charCount) {
  2982.         rightSide = (short) ((**tH).destRect.right);
  2983.         destLeftSide = (short) ((**tH).destRect.left + 1);
  2984.         cursorPt.h = destLeftSide;
  2985.         tabWidth = (long) (**tH).tabWidth;
  2986.         
  2987.         theCharWidths = (**tH).theCharWidths;
  2988.         
  2989.         ch = ' ';
  2990.         
  2991.         while (charCount-- && isneol(ch)) {
  2992.             ch = *charPtr++;
  2993.             lineWidth++;
  2994.             
  2995.             if(wrapToLength)
  2996.                 atLineEnd = (lineWidth > maxLineWidth);
  2997.             else {
  2998.                 if (ch == TAB)
  2999.                     cursorPt.h = destLeftSide + ((cursorPt.h - destLeftSide + tabWidth)/tabWidth)*tabWidth;
  3000.                 else
  3001.                     cursorPt.h += theCharWidths[ch];
  3002.                     
  3003.                 atLineEnd = (cursorPt.h >= rightSide && ch != ' '); 
  3004.             }
  3005.             
  3006.             if (atLineEnd) {
  3007.                 maxRewind = charPtr - charBase - (**tH).lineStarts[thisLine];
  3008.                 oldCharPtr = charPtr;
  3009.                 
  3010.                 charPtr--;
  3011.                 maxRewind--;
  3012.                 
  3013.                 while (*charPtr != ' ' && maxRewind > 0) {
  3014.                     charPtr--;
  3015.                     maxRewind--;
  3016.                 }
  3017.                 
  3018.                 if (maxRewind <= 0)
  3019.                     charPtr = oldCharPtr;
  3020.                 
  3021.                 else
  3022.                     charPtr++;
  3023.                 
  3024.                 charCount = 0;
  3025.             }
  3026.         }
  3027.     }
  3028.     
  3029.     return(charPtr - charBase);
  3030. }
  3031.  
  3032. #define    NUMTEMPLINES    64
  3033.  
  3034. static void CalParagraph(long thisLine,TE32KHandle tH,long *theDeltaLines,long *theNumAffected)
  3035.  
  3036. {
  3037.     register unsigned char    *charPtr;
  3038.     register short            *theCharWidths;
  3039.     register long            charCount,*lineStarts,*otherLine,i;
  3040.     register long            lineWidth,maxLineWidth,tabWidth;
  3041.     register unsigned char    ch;
  3042.     register long            nLines;
  3043.     Boolean                    atLineEnd,wrapToLength;
  3044.     long                    maxLineStarts,sizeTE32KHandle,oldCharCount;
  3045.     unsigned char            *charBase;
  3046.     Point                    cursorPt;
  3047.     short                    rightSide,destLeftSide,maxRewind;
  3048.     unsigned char            *oldCharPtr;
  3049.     long                    tempLineStarts[NUMTEMPLINES],oldNumLines,deltaLines;
  3050.     
  3051.     if ((**tH).crOnly) {
  3052.         *theDeltaLines = 0;
  3053.         *theNumAffected = 0;
  3054.         return;
  3055.     }
  3056.     
  3057.     deltaLines = 0;
  3058.     
  3059.     oldNumLines = paraLines(thisLine,tH);
  3060.     
  3061.     wrapToLength = (**tH).wrapToLength;
  3062.     
  3063.     for (i=0;i<oldNumLines && i <NUMTEMPLINES;i++)
  3064.         tempLineStarts[i] = (**tH).lineStarts[thisLine + i];
  3065.         
  3066.     sizeTE32KHandle  = GetHandleSize((Handle) tH);
  3067.     maxLineStarts = (sizeTE32KHandle - (long) sizeof(TE32KRec))/(long) sizeof(long) - 2;
  3068.     
  3069.     nLines = 0;
  3070.     tempLineStarts[nLines] = (**tH).lineStarts[thisLine];
  3071.     
  3072.     maxLineWidth = (wrapToLength)? (**tH).maxLineWidth : 32767 ;
  3073.     lineWidth = 0;
  3074.     
  3075.     charBase = (unsigned char *) *((**tH).hText);
  3076.     charPtr = charBase + (**tH).lineStarts[thisLine];
  3077.     
  3078.     charCount = (**tH).teLength - (**tH).lineStarts[thisLine];
  3079.     ch = *charPtr;
  3080.     
  3081.     if (charCount > 0) {
  3082.         rightSide = (short) ((**tH).destRect.right);
  3083.         destLeftSide = (short) ((**tH).destRect.left + 1);
  3084.         cursorPt.h = destLeftSide;
  3085.         tabWidth = (long) (**tH).tabWidth;
  3086.         
  3087.         theCharWidths = (**tH).theCharWidths;
  3088.         
  3089.         ch = ' ';
  3090.         
  3091.         while (isneol(ch) && charCount--) {
  3092.             ch = *charPtr++;
  3093.             lineWidth++;
  3094.             
  3095.             if (isneol(ch)) {
  3096.             
  3097.                 if(wrapToLength)
  3098.                     atLineEnd = (lineWidth > maxLineWidth);
  3099.                 else {
  3100.                     if (ch == TAB)
  3101.                         cursorPt.h = destLeftSide + ((cursorPt.h - destLeftSide + tabWidth)/tabWidth)*tabWidth;
  3102.                     else
  3103.                         cursorPt.h += theCharWidths[ch];
  3104.                         
  3105.                     atLineEnd = (cursorPt.h >= rightSide && ch != ' '); 
  3106.                 }
  3107.                 
  3108.                 if (atLineEnd) {
  3109.                     maxRewind = charPtr - charBase - tempLineStarts[nLines];
  3110.                     oldCharPtr = charPtr;
  3111.                     oldCharCount = charCount;
  3112.                     
  3113.                     charPtr--;
  3114.                     charCount++;
  3115.                     maxRewind--;
  3116.                     
  3117.                     while (*charPtr != ' ' && maxRewind > 0) {
  3118.                         charPtr--;
  3119.                         charCount++;
  3120.                         maxRewind--;
  3121.                     }
  3122.                     
  3123.                     if (maxRewind <= 0) {
  3124.                         charPtr = oldCharPtr;
  3125.                         charCount = oldCharCount;
  3126.                     } else {
  3127.                         charPtr++;
  3128.                         charCount--;
  3129.                     }
  3130.                     
  3131.                     nLines++;
  3132.                     
  3133.                     if (nLines < NUMTEMPLINES) {
  3134.                         if (tempLineStarts[nLines] == charPtr - charBase) {
  3135.                             oldNumLines = nLines;
  3136.                             goto STOPWRAPPING;
  3137.                         } else
  3138.                             tempLineStarts[nLines] = charPtr - charBase;
  3139.                     } else
  3140.                         goto STOPWRAPPING;
  3141.                     
  3142.                     cursorPt.h = destLeftSide;
  3143.                     lineWidth = 0;
  3144.                 }
  3145.             }
  3146.         }
  3147.         
  3148.         nLines++;
  3149.         
  3150.         if (nLines < NUMTEMPLINES)
  3151.             tempLineStarts[nLines] = charPtr - charBase;
  3152.  
  3153. STOPWRAPPING:
  3154.  
  3155.         deltaLines = nLines - oldNumLines;
  3156.  
  3157.         if (nLines >= NUMTEMPLINES) {
  3158.             oldNumLines  = (**tH).nLines;
  3159.             TE32KCalText(tH);
  3160.             deltaLines = (**tH).nLines - oldNumLines;
  3161.         } else {
  3162.             if (deltaLines == 0) {
  3163.                 for (i = 1;i <= nLines;i++)
  3164.                     (**tH).lineStarts[thisLine + i] = tempLineStarts[i];
  3165.             }
  3166.             
  3167.             else if (deltaLines < 0) {
  3168.                 lineStarts = &((**tH).lineStarts[thisLine + 1]);
  3169.                 
  3170.                 for (i = 1;i <= nLines;i++)
  3171.                     *(lineStarts++) = tempLineStarts[i];
  3172.                 
  3173.                 otherLine = &((**tH).lineStarts[thisLine + oldNumLines + 1]);
  3174.                 i = (**tH).nLines - thisLine - oldNumLines + 1;
  3175.                 
  3176.                 while (i--)
  3177.                     *(lineStarts++) = *(otherLine++);
  3178.                 
  3179.                 (**tH).nLines += deltaLines;
  3180.             } else {
  3181.                 if ((**tH).nLines + deltaLines >= maxLineStarts) {
  3182.                     sizeTE32KHandle = (long) sizeof(TE32KRec) + (long) sizeof(long)*((**tH).nLines + deltaLines + EXTRALINESTARTS);
  3183.                     maxLineStarts = (sizeTE32KHandle - (long) sizeof(TE32KRec))/(long) sizeof(long) - 2;
  3184.                     
  3185.                     SetHandleSize((Handle) tH,sizeTE32KHandle);
  3186.                     
  3187.                     if (MemError()) {
  3188.                         doMessage(1);
  3189.                         nLines = (**tH).nLines;
  3190.                         deltaLines = (**tH).nLines;
  3191.                         goto EXITPOINT;
  3192.                     }
  3193.                 }
  3194.                 
  3195.                 lineStarts = &((**tH).lineStarts[(**tH).nLines]);
  3196.                 otherLine = &((**tH).lineStarts[(**tH).nLines + deltaLines]);
  3197.                 i = (**tH).nLines - thisLine - oldNumLines;
  3198.                 
  3199.                 while (i--)
  3200.                     *(otherLine--) = *(lineStarts--);
  3201.                     
  3202.                 for (i = nLines;i >= 0;i--)
  3203.                     *(otherLine--) = tempLineStarts[i];
  3204.                 
  3205.                 (**tH).nLines += deltaLines;
  3206.             }
  3207.         }
  3208.     }
  3209.     
  3210. EXITPOINT:
  3211.     *theNumAffected = nLines;
  3212.     *theDeltaLines = deltaLines;
  3213. }
  3214.  
  3215.  
  3216. static void updateLine(register long thisLine, TE32KHandle tH, short doFirst, LongRect *updateClipRect)
  3217. {
  3218.     Rect            tempRect;
  3219.     RgnHandle        updateRgn;
  3220.     LongRect        updateRect;
  3221.     LongPoint        selPt;
  3222.     unsigned char    doWrap;
  3223.     long            deltaLines,numAffected;
  3224.     GrafPtr            oldPort;
  3225.  
  3226.  
  3227.     updateRect = (**tH).viewRect;
  3228.     updateRect.top = (**tH).destRect.top + thisLine * (**tH).lineHeight;
  3229.     updateRect.bottom = updateRect.top + (**tH).lineHeight;
  3230.     
  3231.     if (updateClipRect) {
  3232.         if (updateRect.top < updateClipRect->top)
  3233.             updateRect.top = updateClipRect->top;
  3234.         if (updateRect.bottom > updateClipRect->bottom)
  3235.             updateRect.bottom = updateClipRect->bottom;
  3236.         if (updateRect.left < updateClipRect->left)
  3237.             updateRect.left = updateClipRect->left;
  3238.         if (updateRect.right > updateClipRect->right)
  3239.             updateRect.right = updateClipRect->right;
  3240.     }
  3241.     
  3242.     doWrap = FALSE;
  3243.     
  3244.     if (thisLine > 0 && LineEndIndex(thisLine - 1,tH) != (**tH).lineStarts[thisLine]) {
  3245.         doWrap = TRUE;
  3246.         thisLine--;
  3247.     } else if (LineEndIndex(thisLine,tH) != (**tH).lineStarts[thisLine + 1])
  3248.         doWrap = TRUE;
  3249.     
  3250.     
  3251.     if (!doWrap && doFirst)
  3252.         TE32KUpdate(&updateRect,tH);
  3253.     
  3254.     else if (doWrap) {
  3255.         CalParagraph(thisLine,tH,&deltaLines,&numAffected);
  3256.         
  3257.         if (deltaLines == 0) {
  3258.             updateRect = (**tH).viewRect;
  3259.             updateRect.top = (**tH).destRect.top + thisLine * (**tH).lineHeight;
  3260.             updateRect.bottom = updateRect.top + (**tH).lineHeight * numAffected;
  3261.         } else if (deltaLines > 0) {
  3262.             LongRectToRect(&((**tH).viewRect),&tempRect);
  3263.             tempRect.top = (**tH).destRect.top + (thisLine + numAffected - deltaLines) * (**tH).lineHeight;
  3264.             
  3265.             GetPort(&oldPort);
  3266.             SetPort((**tH).inPort);
  3267.     
  3268.             updateRgn = NewRgn();
  3269.             ScrollRect(&tempRect,0,(**tH).lineHeight * deltaLines,updateRgn);
  3270.             DisposeRgn(updateRgn);
  3271.             
  3272.             SetPort(oldPort);
  3273.             
  3274.             updateRect = (**tH).viewRect;
  3275.             updateRect.top = (**tH).destRect.top + thisLine * (**tH).lineHeight;
  3276.             updateRect.bottom = updateRect.top + (**tH).lineHeight * numAffected;
  3277.         } else {
  3278.             LongRectToRect(&((**tH).viewRect),&tempRect);
  3279.             tempRect.top = (**tH).destRect.top + (thisLine - 1 + numAffected) * (**tH).lineHeight;
  3280.             
  3281.             GetPort(&oldPort);
  3282.             SetPort((**tH).inPort);
  3283.     
  3284.             updateRgn = NewRgn();
  3285.             ScrollRect(&tempRect,0,(**tH).lineHeight * deltaLines,updateRgn);
  3286.             
  3287.             SetPort(oldPort);
  3288.             
  3289.             updateRect.left = (**updateRgn).rgnBBox.left;
  3290.             updateRect.top = (**updateRgn).rgnBBox.top;
  3291.             updateRect.right = (**updateRgn).rgnBBox.right;
  3292.             updateRect.bottom = (**updateRgn).rgnBBox.bottom;
  3293.             
  3294.             DisposeRgn(updateRgn);
  3295.             
  3296.             TE32KUpdate(&updateRect,tH);
  3297.             
  3298.             updateRect = (**tH).viewRect;
  3299.             updateRect.top = (**tH).destRect.top + thisLine * (**tH).lineHeight;
  3300.             updateRect.bottom = updateRect.top + (**tH).lineHeight * numAffected;
  3301.         }
  3302.         
  3303.         TE32KUpdate(&updateRect,tH);
  3304.     }
  3305.  
  3306.     TE32KGetPoint((**tH).selStart,&selPt,tH);
  3307.     (**tH).selPoint = selPt;
  3308. }
  3309.  
  3310. #if 0
  3311.  
  3312. static short    shiftKeyDown()
  3313. {
  3314.     KeyMap    theKeyMap;
  3315.  
  3316.     GetKeys(theKeyMap);
  3317.     
  3318.     if (theKeyMap[1] & 0x01)
  3319.         return(TRUE);
  3320.     else
  3321.         return(FALSE);
  3322. }
  3323.  
  3324.  
  3325. pascal void MyClicker(void)
  3326. {
  3327.     short        lineHeight;
  3328.     Rect        viewRect;
  3329.     Point        mousePoint;
  3330.     RgnHandle    saveClip;
  3331.     long        hDelta,vDelta;
  3332.  
  3333.     if (ClickedTE32KH) {
  3334.         LongRectToRect(&((**ClickedTE32KH).viewRect),&viewRect);
  3335.         lineHeight = (**ClickedTE32KH).lineHeight;
  3336.     
  3337.         hDelta = 0;
  3338.         vDelta = 0;
  3339.         
  3340.         GetMouse(&mousePoint);
  3341.         
  3342.         if (!PtInRect(mousePoint,&viewRect)) {
  3343.             if (mousePoint.v > viewRect.bottom && (**ClickedTE32KH).viewRect.bottom < (**ClickedTE32KH).destRect.top + (long) lineHeight * (**ClickedTE32KH).nLines)
  3344.                 vDelta = -lineHeight;
  3345.             
  3346.             else if (mousePoint.v < viewRect.top && (**ClickedTE32KH).viewRect.top > (**ClickedTE32KH).destRect.top)
  3347.                 vDelta = lineHeight;
  3348.             
  3349.             
  3350.             if (mousePoint.h > viewRect.right && (**ClickedTE32KH).viewRect.right < (**ClickedTE32KH).destRect.right)
  3351.                 hDelta = -lineHeight;
  3352.             
  3353.             else if (mousePoint.h<viewRect.left && (**ClickedTE32KH).viewRect.left > (**ClickedTE32KH).destRect.left)
  3354.                 hDelta = lineHeight;
  3355.         }
  3356.         
  3357.         if (hDelta || vDelta) {
  3358.             saveClip = NewRgn();
  3359.             GetClip(saveClip);
  3360.             viewRect = (*((**ClickedTE32KH).inPort)).portRect;
  3361.             ClipRect(&viewRect);
  3362.             
  3363.             TE32KScroll(hDelta,vDelta,ClickedTE32KH);
  3364.             AdjustScrollBars((**ClickedTE32KH).inPort);
  3365.             SetScrollBarValues((**ClickedTE32KH).inPort);
  3366.             
  3367.             SetClip(saveClip);
  3368.             DisposeRgn(saveClip);
  3369.         }
  3370.     }
  3371. }
  3372. #endif
  3373. void TE32KAutoView(char autoView, TE32KHandle tH)
  3374. {
  3375.     if (tH) {
  3376.         if (!autoView)
  3377.             (**tH).clikLoop = nil;
  3378.         else
  3379.             (**tH).clikLoop = (TE32KProcPtr) MyClicker;
  3380.     }
  3381. }
  3382.  
  3383.